diff --git a/docs/features/differences.md b/docs/features/differences.md index f7cfa6b3..5be19b7a 100644 --- a/docs/features/differences.md +++ b/docs/features/differences.md @@ -35,7 +35,5 @@ The easiest way to test a feature is to [try it on your browser](https://pocketp 4. Raw string cannot have boundary quotes in it, even escaped. See [#55](https://github.com/pocketpy/pocketpy/issues/55). 5. In a starred unpacked assignment, e.g. `a, b, *c = x`, the starred variable can only be presented in the last position. `a, *b, c = x` is not supported. 6. A `Tab` is equivalent to 4 spaces. You can mix `Tab` and spaces in indentation, but it is not recommended. -7. `%`, `&`, `//`, `^` and `|` for `int` behave the same as C, not python. -8. `str.split` and `str.splitlines` will remove all empty entries. -9. A return, break, continue in try/except block will make the finally block not executed. +7. A return, break, continue in try/except/with block will make the finally block not executed. diff --git a/python/collections.py b/python/collections.py index 6e7cdc35..8739d837 100644 --- a/python/collections.py +++ b/python/collections.py @@ -1,8 +1,6 @@ -from typing import Generic, TypeVar, Iterable +from typing import TypeVar, Iterable -T = TypeVar('T') - -def Counter(iterable: Iterable[T]): +def Counter[T](iterable: Iterable[T]): a: dict[T, int] = {} for x in iterable: if x in a: @@ -28,7 +26,7 @@ class defaultdict(dict): return defaultdict(self.default_factory, self) -class deque(Generic[T]): +class deque[T]: _data: list[T] _head: int _tail: int @@ -59,7 +57,7 @@ class deque(Generic[T]): self.__resize_2x() def appendleft(self, x: T): - self._head = (self._head - 1 + self._capacity) % self._capacity + self._head = (self._head - 1) % self._capacity self._data[self._head] = x if (self._tail + 1) % self._capacity == self._head: self.__resize_2x() @@ -85,7 +83,7 @@ class deque(Generic[T]): def pop(self) -> T: if self._head == self._tail: raise IndexError("pop from an empty deque") - self._tail = (self._tail - 1 + self._capacity) % self._capacity + self._tail = (self._tail - 1) % self._capacity return self._data[self._tail] def popleft(self) -> T: @@ -116,7 +114,7 @@ class deque(Generic[T]): self.append(self.popleft()) def __len__(self) -> int: - return (self._tail - self._head + self._capacity) % self._capacity + return (self._tail - self._head) % self._capacity def __contains__(self, x: object) -> bool: for item in self: diff --git a/src/common/_generated.c b/src/common/_generated.c index 1aef80de..d53004f4 100644 --- a/src/common/_generated.c +++ b/src/common/_generated.c @@ -4,7 +4,7 @@ const char kPythonLibs_bisect[] = "\"\"\"Bisection algorithms.\"\"\"\n\ndef insort_right(a, x, lo=0, hi=None):\n \"\"\"Insert item x in list a, and keep it sorted assuming a is sorted.\n\n If x is already in a, insert it to the right of the rightmost x.\n\n Optional args lo (default 0) and hi (default len(a)) bound the\n slice of a to be searched.\n \"\"\"\n\n lo = bisect_right(a, x, lo, hi)\n a.insert(lo, x)\n\ndef bisect_right(a, x, lo=0, hi=None):\n \"\"\"Return the index where to insert item x in list a, assuming a is sorted.\n\n The return value i is such that all e in a[:i] have e <= x, and all e in\n a[i:] have e > x. So if x already appears in the list, a.insert(x) will\n insert just after the rightmost x already there.\n\n Optional args lo (default 0) and hi (default len(a)) bound the\n slice of a to be searched.\n \"\"\"\n\n if lo < 0:\n raise ValueError('lo must be non-negative')\n if hi is None:\n hi = len(a)\n while lo < hi:\n mid = (lo+hi)//2\n if x < a[mid]: hi = mid\n else: lo = mid+1\n return lo\n\ndef insort_left(a, x, lo=0, hi=None):\n \"\"\"Insert item x in list a, and keep it sorted assuming a is sorted.\n\n If x is already in a, insert it to the left of the leftmost x.\n\n Optional args lo (default 0) and hi (default len(a)) bound the\n slice of a to be searched.\n \"\"\"\n\n lo = bisect_left(a, x, lo, hi)\n a.insert(lo, x)\n\n\ndef bisect_left(a, x, lo=0, hi=None):\n \"\"\"Return the index where to insert item x in list a, assuming a is sorted.\n\n The return value i is such that all e in a[:i] have e < x, and all e in\n a[i:] have e >= x. So if x already appears in the list, a.insert(x) will\n insert just before the leftmost x already there.\n\n Optional args lo (default 0) and hi (default len(a)) bound the\n slice of a to be searched.\n \"\"\"\n\n if lo < 0:\n raise ValueError('lo must be non-negative')\n if hi is None:\n hi = len(a)\n while lo < hi:\n mid = (lo+hi)//2\n if a[mid] < x: lo = mid+1\n else: hi = mid\n return lo\n\n# Create aliases\nbisect = bisect_right\ninsort = insort_right\n"; const char kPythonLibs_builtins[] = "def all(iterable):\n for i in iterable:\n if not i:\n return False\n return True\n\ndef any(iterable):\n for i in iterable:\n if i:\n return True\n return False\n\ndef enumerate(iterable, start=0):\n n = start\n for elem in iterable:\n yield n, elem\n n += 1\n\ndef __minmax_reduce(op, args):\n if len(args) == 2: # min(1, 2)\n return args[0] if op(args[0], args[1]) else args[1]\n if len(args) == 0: # min()\n raise TypeError('expected 1 arguments, got 0')\n if len(args) == 1: # min([1, 2, 3, 4]) -> min(1, 2, 3, 4)\n args = args[0]\n args = iter(args)\n try:\n res = next(args)\n except StopIteration:\n raise ValueError('args is an empty sequence')\n while True:\n try:\n i = next(args)\n except StopIteration:\n break\n if op(i, res):\n res = i\n return res\n\ndef min(*args, key=None):\n key = key or (lambda x: x)\n return __minmax_reduce(lambda x,y: key(x)key(y), args)\n\ndef sum(iterable):\n res = 0\n for i in iterable:\n res += i\n return res\n\ndef map(f, iterable):\n for i in iterable:\n yield f(i)\n\ndef filter(f, iterable):\n for i in iterable:\n if f(i):\n yield i\n\ndef zip(a, b):\n a = iter(a)\n b = iter(b)\n while True:\n try:\n ai = next(a)\n bi = next(b)\n except StopIteration:\n break\n yield ai, bi\n\ndef reversed(iterable):\n a = list(iterable)\n a.reverse()\n return a\n\ndef sorted(iterable, key=None, reverse=False):\n a = list(iterable)\n a.sort(key=key, reverse=reverse)\n return a\n\n##### str #####\ndef __format_string(self: str, *args, **kwargs) -> str:\n def tokenizeString(s: str):\n tokens = []\n L, R = 0,0\n \n mode = None\n curArg = 0\n # lookingForKword = False\n \n while(R int:\n n = 0\n for item in self:\n if item == x:\n n += 1\n return n\n \n def extend(self, iterable: Iterable[T]):\n for x in iterable:\n self.append(x)\n\n def extendleft(self, iterable: Iterable[T]):\n for x in iterable:\n self.appendleft(x)\n \n def pop(self) -> T:\n if self._head == self._tail:\n raise IndexError(\"pop from an empty deque\")\n self._tail = (self._tail - 1 + self._capacity) % self._capacity\n return self._data[self._tail]\n \n def popleft(self) -> T:\n if self._head == self._tail:\n raise IndexError(\"pop from an empty deque\")\n x = self._data[self._head]\n self._head = (self._head + 1) % self._capacity\n return x\n \n def clear(self):\n i = self._head\n while i != self._tail:\n self._data[i] = None # type: ignore\n i = (i + 1) % self._capacity\n self._head = 0\n self._tail = 0\n\n def rotate(self, n: int = 1):\n if len(self) == 0:\n return\n if n > 0:\n n = n % len(self)\n for _ in range(n):\n self.appendleft(self.pop())\n elif n < 0:\n n = -n % len(self)\n for _ in range(n):\n self.append(self.popleft())\n\n def __len__(self) -> int:\n return (self._tail - self._head + self._capacity) % self._capacity\n\n def __contains__(self, x: object) -> bool:\n for item in self:\n if item == x:\n return True\n return False\n \n def __iter__(self):\n i = self._head\n while i != self._tail:\n yield self._data[i]\n i = (i + 1) % self._capacity\n\n def __eq__(self, other: object) -> bool:\n if not isinstance(other, deque):\n return NotImplemented\n if len(self) != len(other):\n return False\n for x, y in zip(self, other):\n if x != y:\n return False\n return True\n \n def __ne__(self, other: object) -> bool:\n if not isinstance(other, deque):\n return NotImplemented\n return not self == other\n \n def __repr__(self) -> str:\n return f\"deque({list(self)!r})\"\n\n"; +const char kPythonLibs_collections[] = "from typing import TypeVar, Iterable\n\ndef Counter[T](iterable: Iterable[T]):\n a: dict[T, int] = {}\n for x in iterable:\n if x in a:\n a[x] += 1\n else:\n a[x] = 1\n return a\n\n\nclass defaultdict(dict):\n def __init__(self, default_factory, *args):\n super().__init__(*args)\n self.default_factory = default_factory\n\n def __missing__(self, key):\n self[key] = self.default_factory()\n return self[key]\n\n def __repr__(self) -> str:\n return f\"defaultdict({self.default_factory}, {super().__repr__()})\"\n\n def copy(self):\n return defaultdict(self.default_factory, self)\n\n\nclass deque[T]:\n _data: list[T]\n _head: int\n _tail: int\n _capacity: int\n\n def __init__(self, iterable: Iterable[T] = None):\n self._data = [None] * 8 # type: ignore\n self._head = 0\n self._tail = 0\n self._capacity = len(self._data)\n\n if iterable is not None:\n self.extend(iterable)\n\n def __resize_2x(self):\n backup = list(self)\n self._capacity *= 2\n self._head = 0\n self._tail = len(backup)\n self._data.clear()\n self._data.extend(backup)\n self._data.extend([None] * (self._capacity - len(backup)))\n\n def append(self, x: T):\n self._data[self._tail] = x\n self._tail = (self._tail + 1) % self._capacity\n if (self._tail + 1) % self._capacity == self._head:\n self.__resize_2x()\n\n def appendleft(self, x: T):\n self._head = (self._head - 1) % self._capacity\n self._data[self._head] = x\n if (self._tail + 1) % self._capacity == self._head:\n self.__resize_2x()\n\n def copy(self):\n return deque(self)\n \n def count(self, x: T) -> int:\n n = 0\n for item in self:\n if item == x:\n n += 1\n return n\n \n def extend(self, iterable: Iterable[T]):\n for x in iterable:\n self.append(x)\n\n def extendleft(self, iterable: Iterable[T]):\n for x in iterable:\n self.appendleft(x)\n \n def pop(self) -> T:\n if self._head == self._tail:\n raise IndexError(\"pop from an empty deque\")\n self._tail = (self._tail - 1) % self._capacity\n return self._data[self._tail]\n \n def popleft(self) -> T:\n if self._head == self._tail:\n raise IndexError(\"pop from an empty deque\")\n x = self._data[self._head]\n self._head = (self._head + 1) % self._capacity\n return x\n \n def clear(self):\n i = self._head\n while i != self._tail:\n self._data[i] = None # type: ignore\n i = (i + 1) % self._capacity\n self._head = 0\n self._tail = 0\n\n def rotate(self, n: int = 1):\n if len(self) == 0:\n return\n if n > 0:\n n = n % len(self)\n for _ in range(n):\n self.appendleft(self.pop())\n elif n < 0:\n n = -n % len(self)\n for _ in range(n):\n self.append(self.popleft())\n\n def __len__(self) -> int:\n return (self._tail - self._head) % self._capacity\n\n def __contains__(self, x: object) -> bool:\n for item in self:\n if item == x:\n return True\n return False\n \n def __iter__(self):\n i = self._head\n while i != self._tail:\n yield self._data[i]\n i = (i + 1) % self._capacity\n\n def __eq__(self, other: object) -> bool:\n if not isinstance(other, deque):\n return NotImplemented\n if len(self) != len(other):\n return False\n for x, y in zip(self, other):\n if x != y:\n return False\n return True\n \n def __ne__(self, other: object) -> bool:\n if not isinstance(other, deque):\n return NotImplemented\n return not self == other\n \n def __repr__(self) -> str:\n return f\"deque({list(self)!r})\"\n\n"; const char kPythonLibs_dataclasses[] = "def _get_annotations(cls: type):\n inherits = []\n while cls is not object:\n inherits.append(cls)\n cls = cls.__base__\n inherits.reverse()\n res = {}\n for cls in inherits:\n res.update(cls.__annotations__)\n return res.keys()\n\ndef _wrapped__init__(self, *args, **kwargs):\n cls = type(self)\n cls_d = cls.__dict__\n fields = _get_annotations(cls)\n i = 0 # index into args\n for field in fields:\n if field in kwargs:\n setattr(self, field, kwargs.pop(field))\n else:\n if i < len(args):\n setattr(self, field, args[i])\n i += 1\n elif field in cls_d: # has default value\n setattr(self, field, cls_d[field])\n else:\n raise TypeError(f\"{cls.__name__} missing required argument {field!r}\")\n if len(args) > i:\n raise TypeError(f\"{cls.__name__} takes {len(fields)} positional arguments but {len(args)} were given\")\n if len(kwargs) > 0:\n raise TypeError(f\"{cls.__name__} got an unexpected keyword argument {next(iter(kwargs))!r}\")\n\ndef _wrapped__repr__(self):\n fields = _get_annotations(type(self))\n obj_d = self.__dict__\n args: list = [f\"{field}={obj_d[field]!r}\" for field in fields]\n return f\"{type(self).__name__}({', '.join(args)})\"\n\ndef _wrapped__eq__(self, other):\n if type(self) is not type(other):\n return False\n fields = _get_annotations(type(self))\n for field in fields:\n if getattr(self, field) != getattr(other, field):\n return False\n return True\n\ndef _wrapped__ne__(self, other):\n return not self.__eq__(other)\n\ndef dataclass(cls: type):\n assert type(cls) is type\n cls_d = cls.__dict__\n if '__init__' not in cls_d:\n cls.__init__ = _wrapped__init__\n if '__repr__' not in cls_d:\n cls.__repr__ = _wrapped__repr__\n if '__eq__' not in cls_d:\n cls.__eq__ = _wrapped__eq__\n if '__ne__' not in cls_d:\n cls.__ne__ = _wrapped__ne__\n fields = _get_annotations(cls)\n has_default = False\n for field in fields:\n if field in cls_d:\n has_default = True\n else:\n if has_default:\n raise TypeError(f\"non-default argument {field!r} follows default argument\")\n return cls\n\ndef asdict(obj) -> dict:\n fields = _get_annotations(type(obj))\n obj_d = obj.__dict__\n return {field: obj_d[field] for field in fields}"; const char kPythonLibs_datetime[] = "from time import localtime\nimport operator\n\nclass timedelta:\n def __init__(self, days=0, seconds=0):\n self.days = days\n self.seconds = seconds\n\n def __repr__(self):\n return f\"datetime.timedelta(days={self.days}, seconds={self.seconds})\"\n\n def __eq__(self, other) -> bool:\n if not isinstance(other, timedelta):\n return NotImplemented\n return (self.days, self.seconds) == (other.days, other.seconds)\n\n def __ne__(self, other) -> bool:\n if not isinstance(other, timedelta):\n return NotImplemented\n return (self.days, self.seconds) != (other.days, other.seconds)\n\n\nclass date:\n def __init__(self, year: int, month: int, day: int):\n self.year = year\n self.month = month\n self.day = day\n\n @staticmethod\n def today():\n t = localtime()\n return date(t.tm_year, t.tm_mon, t.tm_mday)\n \n def __cmp(self, other, op):\n if not isinstance(other, date):\n return NotImplemented\n if self.year != other.year:\n return op(self.year, other.year)\n if self.month != other.month:\n return op(self.month, other.month)\n return op(self.day, other.day)\n\n def __eq__(self, other) -> bool:\n return self.__cmp(other, operator.eq)\n \n def __ne__(self, other) -> bool:\n return self.__cmp(other, operator.ne)\n\n def __lt__(self, other: 'date') -> bool:\n return self.__cmp(other, operator.lt)\n\n def __le__(self, other: 'date') -> bool:\n return self.__cmp(other, operator.le)\n\n def __gt__(self, other: 'date') -> bool:\n return self.__cmp(other, operator.gt)\n\n def __ge__(self, other: 'date') -> bool:\n return self.__cmp(other, operator.ge)\n\n def __str__(self):\n return f\"{self.year}-{self.month:02}-{self.day:02}\"\n\n def __repr__(self):\n return f\"datetime.date({self.year}, {self.month}, {self.day})\"\n\n\nclass datetime(date):\n def __init__(self, year: int, month: int, day: int, hour: int, minute: int, second: int):\n super().__init__(year, month, day)\n # Validate and set hour, minute, and second\n if not 0 <= hour <= 23:\n raise ValueError(\"Hour must be between 0 and 23\")\n self.hour = hour\n if not 0 <= minute <= 59:\n raise ValueError(\"Minute must be between 0 and 59\")\n self.minute = minute\n if not 0 <= second <= 59:\n raise ValueError(\"Second must be between 0 and 59\")\n self.second = second\n\n def date(self) -> date:\n return date(self.year, self.month, self.day)\n\n @staticmethod\n def now():\n t = localtime()\n tm_sec = t.tm_sec\n if tm_sec == 60:\n tm_sec = 59\n return datetime(t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, tm_sec)\n\n def __str__(self):\n return f\"{self.year}-{self.month:02}-{self.day:02} {self.hour:02}:{self.minute:02}:{self.second:02}\"\n\n def __repr__(self):\n return f\"datetime.datetime({self.year}, {self.month}, {self.day}, {self.hour}, {self.minute}, {self.second})\"\n\n def __cmp(self, other, op):\n if not isinstance(other, datetime):\n return NotImplemented\n if self.year != other.year:\n return op(self.year, other.year)\n if self.month != other.month:\n return op(self.month, other.month)\n if self.day != other.day:\n return op(self.day, other.day)\n if self.hour != other.hour:\n return op(self.hour, other.hour)\n if self.minute != other.minute:\n return op(self.minute, other.minute)\n return op(self.second, other.second)\n\n def __eq__(self, other) -> bool:\n return self.__cmp(other, operator.eq)\n \n def __ne__(self, other) -> bool:\n return self.__cmp(other, operator.ne)\n \n def __lt__(self, other) -> bool:\n return self.__cmp(other, operator.lt)\n \n def __le__(self, other) -> bool:\n return self.__cmp(other, operator.le)\n \n def __gt__(self, other) -> bool:\n return self.__cmp(other, operator.gt)\n \n def __ge__(self, other) -> bool:\n return self.__cmp(other, operator.ge)\n\n\n"; const char kPythonLibs_functools[] = "class cache:\n def __init__(self, f):\n self.f = f\n self.cache = {}\n\n def __call__(self, *args):\n if args not in self.cache:\n self.cache[args] = self.f(*args)\n return self.cache[args]\n \ndef reduce(function, sequence, initial=...):\n it = iter(sequence)\n if initial is ...:\n try:\n value = next(it)\n except StopIteration:\n raise TypeError(\"reduce() of empty sequence with no initial value\")\n else:\n value = initial\n for element in it:\n value = function(value, element)\n return value\n\nclass partial:\n def __init__(self, f, *args, **kwargs):\n self.f = f\n if not callable(f):\n raise TypeError(\"the first argument must be callable\")\n self.args = args\n self.kwargs = kwargs\n\n def __call__(self, *args, **kwargs):\n kwargs.update(self.kwargs)\n return self.f(*self.args, *args, **kwargs)\n\n"; diff --git a/src/public/py_number.c b/src/public/py_number.c index ff3f1b9f..aa8a9dcf 100644 --- a/src/public/py_number.c +++ b/src/public/py_number.c @@ -123,13 +123,35 @@ static bool number__pow__(int argc, py_Ref argv) { return true; } +static py_i64 cpy11__fast_floor_div(py_i64 a, py_i64 b) { + assert(b != 0); + if(a == 0) return 0; + if((a < 0) == (b < 0)) { + return labs(a) / labs(b); + } else { + return -1 - (labs(a) - 1) / labs(b); + } +} + +static py_i64 cpy11__fast_mod(py_i64 a, py_i64 b) { + assert(b != 0); + if(a == 0) return 0; + py_i64 res; + if((a < 0) == (b < 0)) { + res = labs(a) % labs(b); + } else { + res = labs(b) - 1 - (labs(a) - 1) % labs(b); + } + return b < 0 ? -res : res; +} + static bool int__floordiv__(int argc, py_Ref argv) { PY_CHECK_ARGC(2); py_i64 lhs = py_toint(&argv[0]); if(py_isint(&argv[1])) { py_i64 rhs = py_toint(&argv[1]); - if(rhs == 0) return ZeroDivisionError("integer division or modulo by zero"); - py_newint(py_retval(), lhs / rhs); + if(rhs == 0) return ZeroDivisionError("integer division by zero"); + py_newint(py_retval(), cpy11__fast_floor_div(lhs, rhs)); } else { py_newnotimplemented(py_retval()); } @@ -141,8 +163,8 @@ static bool int__mod__(int argc, py_Ref argv) { py_i64 lhs = py_toint(&argv[0]); if(py_isint(&argv[1])) { py_i64 rhs = py_toint(&argv[1]); - if(rhs == 0) return ZeroDivisionError("integer division or modulo by zero"); - py_newint(py_retval(), lhs % rhs); + if(rhs == 0) return ZeroDivisionError("integer modulo by zero"); + py_newint(py_retval(), cpy11__fast_mod(lhs, rhs)); } else { py_newnotimplemented(py_retval()); } @@ -156,9 +178,8 @@ static bool int__divmod__(int argc, py_Ref argv) { py_i64 rhs = py_toint(&argv[1]); if(rhs == 0) return ZeroDivisionError("integer division or modulo by zero"); py_newtuple(py_retval(), 2); - ldiv_t res = ldiv(lhs, rhs); - py_newint(py_getslot(py_retval(), 0), res.quot); - py_newint(py_getslot(py_retval(), 1), res.rem); + py_newint(py_getslot(py_retval(), 0), cpy11__fast_floor_div(lhs, rhs)); + py_newint(py_getslot(py_retval(), 1), cpy11__fast_mod(lhs, rhs)); return true; } @@ -291,7 +312,7 @@ static bool int__new__(int argc, py_Ref argv) { return true; } case tp_str: break; // leave to the next block - default: return pk_callmagic(__int__, 1, argv+1); + default: return pk_callmagic(__int__, 1, argv + 1); } } // 2+ args -> error @@ -363,7 +384,7 @@ static bool float__new__(int argc, py_Ref argv) { py_newfloat(py_retval(), float_out); return true; } - default: return pk_callmagic(__float__, 1, argv+1); + default: return pk_callmagic(__float__, 1, argv + 1); } } diff --git a/tests/01_int.py b/tests/01_int.py index 71461034..88d25883 100644 --- a/tests/01_int.py +++ b/tests/01_int.py @@ -111,45 +111,764 @@ assert abs(0) == 0 assert abs(1) == 1 assert abs(-1) == 1 -# try: -# 1 // 0 -# exit(1) -# except ZeroDivisionError: -# pass - -# try: -# 1 % 0 -# exit(1) -# except ZeroDivisionError: -# pass - -# try: -# 2**60 // 0 -# exit(1) -# except ZeroDivisionError: -# pass - -# try: -# 2**60 % 0 -# exit(1) -# except ZeroDivisionError: -# pass - -# try: -# divmod(1, 0) -# exit(1) -# except ZeroDivisionError: -# pass - -# try: -# divmod(2**60, 0) -# exit(1) -# except ZeroDivisionError: -# pass - -# try: -# x = eval("231231312312312312312312312312312312314354657553423345632") -# print(f"eval should fail, but got {x!r}") -# exit(1) -# except SyntaxError: -# pass \ No newline at end of file +# test negative % and // +assert -10 % -10 == 0 +assert -10 // -10 == 1 +assert -10 % -9 == -1 +assert -10 // -9 == 1 +assert -10 % -8 == -2 +assert -10 // -8 == 1 +assert -10 % -7 == -3 +assert -10 // -7 == 1 +assert -10 % -6 == -4 +assert -10 // -6 == 1 +assert -10 % -5 == 0 +assert -10 // -5 == 2 +assert -10 % -4 == -2 +assert -10 // -4 == 2 +assert -10 % -3 == -1 +assert -10 // -3 == 3 +assert -10 % -2 == 0 +assert -10 // -2 == 5 +assert -10 % -1 == 0 +assert -10 // -1 == 10 +assert -10 % 1 == 0 +assert -10 // 1 == -10 +assert -10 % 2 == 0 +assert -10 // 2 == -5 +assert -10 % 3 == 2 +assert -10 // 3 == -4 +assert -10 % 4 == 2 +assert -10 // 4 == -3 +assert -10 % 5 == 0 +assert -10 // 5 == -2 +assert -10 % 6 == 2 +assert -10 // 6 == -2 +assert -10 % 7 == 4 +assert -10 // 7 == -2 +assert -10 % 8 == 6 +assert -10 // 8 == -2 +assert -10 % 9 == 8 +assert -10 // 9 == -2 +assert -9 % -10 == -9 +assert -9 // -10 == 0 +assert -9 % -9 == 0 +assert -9 // -9 == 1 +assert -9 % -8 == -1 +assert -9 // -8 == 1 +assert -9 % -7 == -2 +assert -9 // -7 == 1 +assert -9 % -6 == -3 +assert -9 // -6 == 1 +assert -9 % -5 == -4 +assert -9 // -5 == 1 +assert -9 % -4 == -1 +assert -9 // -4 == 2 +assert -9 % -3 == 0 +assert -9 // -3 == 3 +assert -9 % -2 == -1 +assert -9 // -2 == 4 +assert -9 % -1 == 0 +assert -9 // -1 == 9 +assert -9 % 1 == 0 +assert -9 // 1 == -9 +assert -9 % 2 == 1 +assert -9 // 2 == -5 +assert -9 % 3 == 0 +assert -9 // 3 == -3 +assert -9 % 4 == 3 +assert -9 // 4 == -3 +assert -9 % 5 == 1 +assert -9 // 5 == -2 +assert -9 % 6 == 3 +assert -9 // 6 == -2 +assert -9 % 7 == 5 +assert -9 // 7 == -2 +assert -9 % 8 == 7 +assert -9 // 8 == -2 +assert -9 % 9 == 0 +assert -9 // 9 == -1 +assert -8 % -10 == -8 +assert -8 // -10 == 0 +assert -8 % -9 == -8 +assert -8 // -9 == 0 +assert -8 % -8 == 0 +assert -8 // -8 == 1 +assert -8 % -7 == -1 +assert -8 // -7 == 1 +assert -8 % -6 == -2 +assert -8 // -6 == 1 +assert -8 % -5 == -3 +assert -8 // -5 == 1 +assert -8 % -4 == 0 +assert -8 // -4 == 2 +assert -8 % -3 == -2 +assert -8 // -3 == 2 +assert -8 % -2 == 0 +assert -8 // -2 == 4 +assert -8 % -1 == 0 +assert -8 // -1 == 8 +assert -8 % 1 == 0 +assert -8 // 1 == -8 +assert -8 % 2 == 0 +assert -8 // 2 == -4 +assert -8 % 3 == 1 +assert -8 // 3 == -3 +assert -8 % 4 == 0 +assert -8 // 4 == -2 +assert -8 % 5 == 2 +assert -8 // 5 == -2 +assert -8 % 6 == 4 +assert -8 // 6 == -2 +assert -8 % 7 == 6 +assert -8 // 7 == -2 +assert -8 % 8 == 0 +assert -8 // 8 == -1 +assert -8 % 9 == 1 +assert -8 // 9 == -1 +assert -7 % -10 == -7 +assert -7 // -10 == 0 +assert -7 % -9 == -7 +assert -7 // -9 == 0 +assert -7 % -8 == -7 +assert -7 // -8 == 0 +assert -7 % -7 == 0 +assert -7 // -7 == 1 +assert -7 % -6 == -1 +assert -7 // -6 == 1 +assert -7 % -5 == -2 +assert -7 // -5 == 1 +assert -7 % -4 == -3 +assert -7 // -4 == 1 +assert -7 % -3 == -1 +assert -7 // -3 == 2 +assert -7 % -2 == -1 +assert -7 // -2 == 3 +assert -7 % -1 == 0 +assert -7 // -1 == 7 +assert -7 % 1 == 0 +assert -7 // 1 == -7 +assert -7 % 2 == 1 +assert -7 // 2 == -4 +assert -7 % 3 == 2 +assert -7 // 3 == -3 +assert -7 % 4 == 1 +assert -7 // 4 == -2 +assert -7 % 5 == 3 +assert -7 // 5 == -2 +assert -7 % 6 == 5 +assert -7 // 6 == -2 +assert -7 % 7 == 0 +assert -7 // 7 == -1 +assert -7 % 8 == 1 +assert -7 // 8 == -1 +assert -7 % 9 == 2 +assert -7 // 9 == -1 +assert -6 % -10 == -6 +assert -6 // -10 == 0 +assert -6 % -9 == -6 +assert -6 // -9 == 0 +assert -6 % -8 == -6 +assert -6 // -8 == 0 +assert -6 % -7 == -6 +assert -6 // -7 == 0 +assert -6 % -6 == 0 +assert -6 // -6 == 1 +assert -6 % -5 == -1 +assert -6 // -5 == 1 +assert -6 % -4 == -2 +assert -6 // -4 == 1 +assert -6 % -3 == 0 +assert -6 // -3 == 2 +assert -6 % -2 == 0 +assert -6 // -2 == 3 +assert -6 % -1 == 0 +assert -6 // -1 == 6 +assert -6 % 1 == 0 +assert -6 // 1 == -6 +assert -6 % 2 == 0 +assert -6 // 2 == -3 +assert -6 % 3 == 0 +assert -6 // 3 == -2 +assert -6 % 4 == 2 +assert -6 // 4 == -2 +assert -6 % 5 == 4 +assert -6 // 5 == -2 +assert -6 % 6 == 0 +assert -6 // 6 == -1 +assert -6 % 7 == 1 +assert -6 // 7 == -1 +assert -6 % 8 == 2 +assert -6 // 8 == -1 +assert -6 % 9 == 3 +assert -6 // 9 == -1 +assert -5 % -10 == -5 +assert -5 // -10 == 0 +assert -5 % -9 == -5 +assert -5 // -9 == 0 +assert -5 % -8 == -5 +assert -5 // -8 == 0 +assert -5 % -7 == -5 +assert -5 // -7 == 0 +assert -5 % -6 == -5 +assert -5 // -6 == 0 +assert -5 % -5 == 0 +assert -5 // -5 == 1 +assert -5 % -4 == -1 +assert -5 // -4 == 1 +assert -5 % -3 == -2 +assert -5 // -3 == 1 +assert -5 % -2 == -1 +assert -5 // -2 == 2 +assert -5 % -1 == 0 +assert -5 // -1 == 5 +assert -5 % 1 == 0 +assert -5 // 1 == -5 +assert -5 % 2 == 1 +assert -5 // 2 == -3 +assert -5 % 3 == 1 +assert -5 // 3 == -2 +assert -5 % 4 == 3 +assert -5 // 4 == -2 +assert -5 % 5 == 0 +assert -5 // 5 == -1 +assert -5 % 6 == 1 +assert -5 // 6 == -1 +assert -5 % 7 == 2 +assert -5 // 7 == -1 +assert -5 % 8 == 3 +assert -5 // 8 == -1 +assert -5 % 9 == 4 +assert -5 // 9 == -1 +assert -4 % -10 == -4 +assert -4 // -10 == 0 +assert -4 % -9 == -4 +assert -4 // -9 == 0 +assert -4 % -8 == -4 +assert -4 // -8 == 0 +assert -4 % -7 == -4 +assert -4 // -7 == 0 +assert -4 % -6 == -4 +assert -4 // -6 == 0 +assert -4 % -5 == -4 +assert -4 // -5 == 0 +assert -4 % -4 == 0 +assert -4 // -4 == 1 +assert -4 % -3 == -1 +assert -4 // -3 == 1 +assert -4 % -2 == 0 +assert -4 // -2 == 2 +assert -4 % -1 == 0 +assert -4 // -1 == 4 +assert -4 % 1 == 0 +assert -4 // 1 == -4 +assert -4 % 2 == 0 +assert -4 // 2 == -2 +assert -4 % 3 == 2 +assert -4 // 3 == -2 +assert -4 % 4 == 0 +assert -4 // 4 == -1 +assert -4 % 5 == 1 +assert -4 // 5 == -1 +assert -4 % 6 == 2 +assert -4 // 6 == -1 +assert -4 % 7 == 3 +assert -4 // 7 == -1 +assert -4 % 8 == 4 +assert -4 // 8 == -1 +assert -4 % 9 == 5 +assert -4 // 9 == -1 +assert -3 % -10 == -3 +assert -3 // -10 == 0 +assert -3 % -9 == -3 +assert -3 // -9 == 0 +assert -3 % -8 == -3 +assert -3 // -8 == 0 +assert -3 % -7 == -3 +assert -3 // -7 == 0 +assert -3 % -6 == -3 +assert -3 // -6 == 0 +assert -3 % -5 == -3 +assert -3 // -5 == 0 +assert -3 % -4 == -3 +assert -3 // -4 == 0 +assert -3 % -3 == 0 +assert -3 // -3 == 1 +assert -3 % -2 == -1 +assert -3 // -2 == 1 +assert -3 % -1 == 0 +assert -3 // -1 == 3 +assert -3 % 1 == 0 +assert -3 // 1 == -3 +assert -3 % 2 == 1 +assert -3 // 2 == -2 +assert -3 % 3 == 0 +assert -3 // 3 == -1 +assert -3 % 4 == 1 +assert -3 // 4 == -1 +assert -3 % 5 == 2 +assert -3 // 5 == -1 +assert -3 % 6 == 3 +assert -3 // 6 == -1 +assert -3 % 7 == 4 +assert -3 // 7 == -1 +assert -3 % 8 == 5 +assert -3 // 8 == -1 +assert -3 % 9 == 6 +assert -3 // 9 == -1 +assert -2 % -10 == -2 +assert -2 // -10 == 0 +assert -2 % -9 == -2 +assert -2 // -9 == 0 +assert -2 % -8 == -2 +assert -2 // -8 == 0 +assert -2 % -7 == -2 +assert -2 // -7 == 0 +assert -2 % -6 == -2 +assert -2 // -6 == 0 +assert -2 % -5 == -2 +assert -2 // -5 == 0 +assert -2 % -4 == -2 +assert -2 // -4 == 0 +assert -2 % -3 == -2 +assert -2 // -3 == 0 +assert -2 % -2 == 0 +assert -2 // -2 == 1 +assert -2 % -1 == 0 +assert -2 // -1 == 2 +assert -2 % 1 == 0 +assert -2 // 1 == -2 +assert -2 % 2 == 0 +assert -2 // 2 == -1 +assert -2 % 3 == 1 +assert -2 // 3 == -1 +assert -2 % 4 == 2 +assert -2 // 4 == -1 +assert -2 % 5 == 3 +assert -2 // 5 == -1 +assert -2 % 6 == 4 +assert -2 // 6 == -1 +assert -2 % 7 == 5 +assert -2 // 7 == -1 +assert -2 % 8 == 6 +assert -2 // 8 == -1 +assert -2 % 9 == 7 +assert -2 // 9 == -1 +assert -1 % -10 == -1 +assert -1 // -10 == 0 +assert -1 % -9 == -1 +assert -1 // -9 == 0 +assert -1 % -8 == -1 +assert -1 // -8 == 0 +assert -1 % -7 == -1 +assert -1 // -7 == 0 +assert -1 % -6 == -1 +assert -1 // -6 == 0 +assert -1 % -5 == -1 +assert -1 // -5 == 0 +assert -1 % -4 == -1 +assert -1 // -4 == 0 +assert -1 % -3 == -1 +assert -1 // -3 == 0 +assert -1 % -2 == -1 +assert -1 // -2 == 0 +assert -1 % -1 == 0 +assert -1 // -1 == 1 +assert -1 % 1 == 0 +assert -1 // 1 == -1 +assert -1 % 2 == 1 +assert -1 // 2 == -1 +assert -1 % 3 == 2 +assert -1 // 3 == -1 +assert -1 % 4 == 3 +assert -1 // 4 == -1 +assert -1 % 5 == 4 +assert -1 // 5 == -1 +assert -1 % 6 == 5 +assert -1 // 6 == -1 +assert -1 % 7 == 6 +assert -1 // 7 == -1 +assert -1 % 8 == 7 +assert -1 // 8 == -1 +assert -1 % 9 == 8 +assert -1 // 9 == -1 +assert 0 % -10 == 0 +assert 0 // -10 == 0 +assert 0 % -9 == 0 +assert 0 // -9 == 0 +assert 0 % -8 == 0 +assert 0 // -8 == 0 +assert 0 % -7 == 0 +assert 0 // -7 == 0 +assert 0 % -6 == 0 +assert 0 // -6 == 0 +assert 0 % -5 == 0 +assert 0 // -5 == 0 +assert 0 % -4 == 0 +assert 0 // -4 == 0 +assert 0 % -3 == 0 +assert 0 // -3 == 0 +assert 0 % -2 == 0 +assert 0 // -2 == 0 +assert 0 % -1 == 0 +assert 0 // -1 == 0 +assert 0 % 1 == 0 +assert 0 // 1 == 0 +assert 0 % 2 == 0 +assert 0 // 2 == 0 +assert 0 % 3 == 0 +assert 0 // 3 == 0 +assert 0 % 4 == 0 +assert 0 // 4 == 0 +assert 0 % 5 == 0 +assert 0 // 5 == 0 +assert 0 % 6 == 0 +assert 0 // 6 == 0 +assert 0 % 7 == 0 +assert 0 // 7 == 0 +assert 0 % 8 == 0 +assert 0 // 8 == 0 +assert 0 % 9 == 0 +assert 0 // 9 == 0 +assert 1 % -10 == -9 +assert 1 // -10 == -1 +assert 1 % -9 == -8 +assert 1 // -9 == -1 +assert 1 % -8 == -7 +assert 1 // -8 == -1 +assert 1 % -7 == -6 +assert 1 // -7 == -1 +assert 1 % -6 == -5 +assert 1 // -6 == -1 +assert 1 % -5 == -4 +assert 1 // -5 == -1 +assert 1 % -4 == -3 +assert 1 // -4 == -1 +assert 1 % -3 == -2 +assert 1 // -3 == -1 +assert 1 % -2 == -1 +assert 1 // -2 == -1 +assert 1 % -1 == 0 +assert 1 // -1 == -1 +assert 1 % 1 == 0 +assert 1 // 1 == 1 +assert 1 % 2 == 1 +assert 1 // 2 == 0 +assert 1 % 3 == 1 +assert 1 // 3 == 0 +assert 1 % 4 == 1 +assert 1 // 4 == 0 +assert 1 % 5 == 1 +assert 1 // 5 == 0 +assert 1 % 6 == 1 +assert 1 // 6 == 0 +assert 1 % 7 == 1 +assert 1 // 7 == 0 +assert 1 % 8 == 1 +assert 1 // 8 == 0 +assert 1 % 9 == 1 +assert 1 // 9 == 0 +assert 2 % -10 == -8 +assert 2 // -10 == -1 +assert 2 % -9 == -7 +assert 2 // -9 == -1 +assert 2 % -8 == -6 +assert 2 // -8 == -1 +assert 2 % -7 == -5 +assert 2 // -7 == -1 +assert 2 % -6 == -4 +assert 2 // -6 == -1 +assert 2 % -5 == -3 +assert 2 // -5 == -1 +assert 2 % -4 == -2 +assert 2 // -4 == -1 +assert 2 % -3 == -1 +assert 2 // -3 == -1 +assert 2 % -2 == 0 +assert 2 // -2 == -1 +assert 2 % -1 == 0 +assert 2 // -1 == -2 +assert 2 % 1 == 0 +assert 2 // 1 == 2 +assert 2 % 2 == 0 +assert 2 // 2 == 1 +assert 2 % 3 == 2 +assert 2 // 3 == 0 +assert 2 % 4 == 2 +assert 2 // 4 == 0 +assert 2 % 5 == 2 +assert 2 // 5 == 0 +assert 2 % 6 == 2 +assert 2 // 6 == 0 +assert 2 % 7 == 2 +assert 2 // 7 == 0 +assert 2 % 8 == 2 +assert 2 // 8 == 0 +assert 2 % 9 == 2 +assert 2 // 9 == 0 +assert 3 % -10 == -7 +assert 3 // -10 == -1 +assert 3 % -9 == -6 +assert 3 // -9 == -1 +assert 3 % -8 == -5 +assert 3 // -8 == -1 +assert 3 % -7 == -4 +assert 3 // -7 == -1 +assert 3 % -6 == -3 +assert 3 // -6 == -1 +assert 3 % -5 == -2 +assert 3 // -5 == -1 +assert 3 % -4 == -1 +assert 3 // -4 == -1 +assert 3 % -3 == 0 +assert 3 // -3 == -1 +assert 3 % -2 == -1 +assert 3 // -2 == -2 +assert 3 % -1 == 0 +assert 3 // -1 == -3 +assert 3 % 1 == 0 +assert 3 // 1 == 3 +assert 3 % 2 == 1 +assert 3 // 2 == 1 +assert 3 % 3 == 0 +assert 3 // 3 == 1 +assert 3 % 4 == 3 +assert 3 // 4 == 0 +assert 3 % 5 == 3 +assert 3 // 5 == 0 +assert 3 % 6 == 3 +assert 3 // 6 == 0 +assert 3 % 7 == 3 +assert 3 // 7 == 0 +assert 3 % 8 == 3 +assert 3 // 8 == 0 +assert 3 % 9 == 3 +assert 3 // 9 == 0 +assert 4 % -10 == -6 +assert 4 // -10 == -1 +assert 4 % -9 == -5 +assert 4 // -9 == -1 +assert 4 % -8 == -4 +assert 4 // -8 == -1 +assert 4 % -7 == -3 +assert 4 // -7 == -1 +assert 4 % -6 == -2 +assert 4 // -6 == -1 +assert 4 % -5 == -1 +assert 4 // -5 == -1 +assert 4 % -4 == 0 +assert 4 // -4 == -1 +assert 4 % -3 == -2 +assert 4 // -3 == -2 +assert 4 % -2 == 0 +assert 4 // -2 == -2 +assert 4 % -1 == 0 +assert 4 // -1 == -4 +assert 4 % 1 == 0 +assert 4 // 1 == 4 +assert 4 % 2 == 0 +assert 4 // 2 == 2 +assert 4 % 3 == 1 +assert 4 // 3 == 1 +assert 4 % 4 == 0 +assert 4 // 4 == 1 +assert 4 % 5 == 4 +assert 4 // 5 == 0 +assert 4 % 6 == 4 +assert 4 // 6 == 0 +assert 4 % 7 == 4 +assert 4 // 7 == 0 +assert 4 % 8 == 4 +assert 4 // 8 == 0 +assert 4 % 9 == 4 +assert 4 // 9 == 0 +assert 5 % -10 == -5 +assert 5 // -10 == -1 +assert 5 % -9 == -4 +assert 5 // -9 == -1 +assert 5 % -8 == -3 +assert 5 // -8 == -1 +assert 5 % -7 == -2 +assert 5 // -7 == -1 +assert 5 % -6 == -1 +assert 5 // -6 == -1 +assert 5 % -5 == 0 +assert 5 // -5 == -1 +assert 5 % -4 == -3 +assert 5 // -4 == -2 +assert 5 % -3 == -1 +assert 5 // -3 == -2 +assert 5 % -2 == -1 +assert 5 // -2 == -3 +assert 5 % -1 == 0 +assert 5 // -1 == -5 +assert 5 % 1 == 0 +assert 5 // 1 == 5 +assert 5 % 2 == 1 +assert 5 // 2 == 2 +assert 5 % 3 == 2 +assert 5 // 3 == 1 +assert 5 % 4 == 1 +assert 5 // 4 == 1 +assert 5 % 5 == 0 +assert 5 // 5 == 1 +assert 5 % 6 == 5 +assert 5 // 6 == 0 +assert 5 % 7 == 5 +assert 5 // 7 == 0 +assert 5 % 8 == 5 +assert 5 // 8 == 0 +assert 5 % 9 == 5 +assert 5 // 9 == 0 +assert 6 % -10 == -4 +assert 6 // -10 == -1 +assert 6 % -9 == -3 +assert 6 // -9 == -1 +assert 6 % -8 == -2 +assert 6 // -8 == -1 +assert 6 % -7 == -1 +assert 6 // -7 == -1 +assert 6 % -6 == 0 +assert 6 // -6 == -1 +assert 6 % -5 == -4 +assert 6 // -5 == -2 +assert 6 % -4 == -2 +assert 6 // -4 == -2 +assert 6 % -3 == 0 +assert 6 // -3 == -2 +assert 6 % -2 == 0 +assert 6 // -2 == -3 +assert 6 % -1 == 0 +assert 6 // -1 == -6 +assert 6 % 1 == 0 +assert 6 // 1 == 6 +assert 6 % 2 == 0 +assert 6 // 2 == 3 +assert 6 % 3 == 0 +assert 6 // 3 == 2 +assert 6 % 4 == 2 +assert 6 // 4 == 1 +assert 6 % 5 == 1 +assert 6 // 5 == 1 +assert 6 % 6 == 0 +assert 6 // 6 == 1 +assert 6 % 7 == 6 +assert 6 // 7 == 0 +assert 6 % 8 == 6 +assert 6 // 8 == 0 +assert 6 % 9 == 6 +assert 6 // 9 == 0 +assert 7 % -10 == -3 +assert 7 // -10 == -1 +assert 7 % -9 == -2 +assert 7 // -9 == -1 +assert 7 % -8 == -1 +assert 7 // -8 == -1 +assert 7 % -7 == 0 +assert 7 // -7 == -1 +assert 7 % -6 == -5 +assert 7 // -6 == -2 +assert 7 % -5 == -3 +assert 7 // -5 == -2 +assert 7 % -4 == -1 +assert 7 // -4 == -2 +assert 7 % -3 == -2 +assert 7 // -3 == -3 +assert 7 % -2 == -1 +assert 7 // -2 == -4 +assert 7 % -1 == 0 +assert 7 // -1 == -7 +assert 7 % 1 == 0 +assert 7 // 1 == 7 +assert 7 % 2 == 1 +assert 7 // 2 == 3 +assert 7 % 3 == 1 +assert 7 // 3 == 2 +assert 7 % 4 == 3 +assert 7 // 4 == 1 +assert 7 % 5 == 2 +assert 7 // 5 == 1 +assert 7 % 6 == 1 +assert 7 // 6 == 1 +assert 7 % 7 == 0 +assert 7 // 7 == 1 +assert 7 % 8 == 7 +assert 7 // 8 == 0 +assert 7 % 9 == 7 +assert 7 // 9 == 0 +assert 8 % -10 == -2 +assert 8 // -10 == -1 +assert 8 % -9 == -1 +assert 8 // -9 == -1 +assert 8 % -8 == 0 +assert 8 // -8 == -1 +assert 8 % -7 == -6 +assert 8 // -7 == -2 +assert 8 % -6 == -4 +assert 8 // -6 == -2 +assert 8 % -5 == -2 +assert 8 // -5 == -2 +assert 8 % -4 == 0 +assert 8 // -4 == -2 +assert 8 % -3 == -1 +assert 8 // -3 == -3 +assert 8 % -2 == 0 +assert 8 // -2 == -4 +assert 8 % -1 == 0 +assert 8 // -1 == -8 +assert 8 % 1 == 0 +assert 8 // 1 == 8 +assert 8 % 2 == 0 +assert 8 // 2 == 4 +assert 8 % 3 == 2 +assert 8 // 3 == 2 +assert 8 % 4 == 0 +assert 8 // 4 == 2 +assert 8 % 5 == 3 +assert 8 // 5 == 1 +assert 8 % 6 == 2 +assert 8 // 6 == 1 +assert 8 % 7 == 1 +assert 8 // 7 == 1 +assert 8 % 8 == 0 +assert 8 // 8 == 1 +assert 8 % 9 == 8 +assert 8 // 9 == 0 +assert 9 % -10 == -1 +assert 9 // -10 == -1 +assert 9 % -9 == 0 +assert 9 // -9 == -1 +assert 9 % -8 == -7 +assert 9 // -8 == -2 +assert 9 % -7 == -5 +assert 9 // -7 == -2 +assert 9 % -6 == -3 +assert 9 // -6 == -2 +assert 9 % -5 == -1 +assert 9 // -5 == -2 +assert 9 % -4 == -3 +assert 9 // -4 == -3 +assert 9 % -3 == 0 +assert 9 // -3 == -3 +assert 9 % -2 == -1 +assert 9 // -2 == -5 +assert 9 % -1 == 0 +assert 9 // -1 == -9 +assert 9 % 1 == 0 +assert 9 // 1 == 9 +assert 9 % 2 == 1 +assert 9 // 2 == 4 +assert 9 % 3 == 0 +assert 9 // 3 == 3 +assert 9 % 4 == 1 +assert 9 // 4 == 2 +assert 9 % 5 == 4 +assert 9 // 5 == 1 +assert 9 % 6 == 3 +assert 9 // 6 == 1 +assert 9 % 7 == 2 +assert 9 // 7 == 1 +assert 9 % 8 == 1 +assert 9 // 8 == 1 +assert 9 % 9 == 0 +assert 9 // 9 == 1 \ No newline at end of file