| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- from typing import Generic, TypeVar, Iterable
- T = TypeVar('T')
- def Counter(iterable: Iterable[T]):
- a: dict[T, int] = {}
- for x in iterable:
- if x in a:
- a[x] += 1
- else:
- a[x] = 1
- return a
- class defaultdict(dict):
- def __init__(self, default_factory, *args):
- super().__init__(*args)
- self.default_factory = default_factory
- def __missing__(self, key):
- self[key] = self.default_factory()
- return self[key]
- def __repr__(self) -> str:
- return f"defaultdict({self.default_factory}, {super().__repr__()})"
- def copy(self):
- return defaultdict(self.default_factory, self)
- class deque(Generic[T]):
- _data: list[T]
- _head: int
- _tail: int
- _capacity: int
- def __init__(self, iterable: Iterable[T] = None):
- self._data = [None] * 8 # initial capacity
- self._head = 0
- self._tail = 0
- self._capacity = len(self._data)
- if iterable is not None:
- self.extend(iterable)
- def __resize_2x(self):
- backup = list(self)
- self._capacity *= 2
- self._head = 0
- self._tail = len(backup)
- self._data.clear()
- self._data.extend(backup)
- self._data.extend([None] * (self._capacity - len(backup)))
- def append(self, x: T):
- self._data[self._tail] = x
- self._tail = (self._tail + 1) % self._capacity
- if (self._tail + 1) % self._capacity == self._head:
- self.__resize_2x()
- def appendleft(self, x: T):
- self._head = (self._head - 1 + self._capacity) % self._capacity
- self._data[self._head] = x
- if (self._tail + 1) % self._capacity == self._head:
- self.__resize_2x()
- def copy(self):
- return deque(self)
-
- def count(self, x: T) -> int:
- n = 0
- for item in self:
- if item == x:
- n += 1
- return n
-
- def extend(self, iterable: Iterable[T]):
- for x in iterable:
- self.append(x)
- def extendleft(self, iterable: Iterable[T]):
- for x in iterable:
- self.appendleft(x)
-
- 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
- return self._data[self._tail]
-
- def popleft(self) -> T:
- if self._head == self._tail:
- raise IndexError("pop from an empty deque")
- x = self._data[self._head]
- self._head = (self._head + 1) % self._capacity
- return x
-
- def clear(self):
- i = self._head
- while i != self._tail:
- self._data[i] = None
- i = (i + 1) % self._capacity
- self._head = 0
- self._tail = 0
- def rotate(self, n: int = 1):
- if len(self) == 0:
- return
- if n > 0:
- n = n % len(self)
- for _ in range(n):
- self.appendleft(self.pop())
- elif n < 0:
- n = -n % len(self)
- for _ in range(n):
- self.append(self.popleft())
- def __len__(self) -> int:
- return (self._tail - self._head + self._capacity) % self._capacity
- def __contains__(self, x: object) -> bool:
- for item in self:
- if item == x:
- return True
- return False
-
- def __iter__(self):
- i = self._head
- while i != self._tail:
- yield self._data[i]
- i = (i + 1) % self._capacity
- def __eq__(self, other: object) -> bool:
- if not isinstance(other, deque):
- return NotImplemented
- if len(self) != len(other):
- return False
- for x, y in zip(self, other):
- if x != y:
- return False
- return True
-
- def __ne__(self, other: object) -> bool:
- if not isinstance(other, deque):
- return NotImplemented
- return not self == other
-
- def __repr__(self) -> str:
- return f"deque({list(self)!r})"
|