1
0

collections.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. from typing import TypeVar, Iterable
  2. def Counter[T](iterable: Iterable[T]):
  3. a: dict[T, int] = {}
  4. for x in iterable:
  5. if x in a:
  6. a[x] += 1
  7. else:
  8. a[x] = 1
  9. return a
  10. class defaultdict(dict):
  11. def __init__(self, default_factory, *args):
  12. super().__init__(*args)
  13. self.default_factory = default_factory
  14. def __missing__(self, key):
  15. self[key] = self.default_factory()
  16. return self[key]
  17. def __repr__(self) -> str:
  18. return f"defaultdict({self.default_factory}, {super().__repr__()})"
  19. def copy(self):
  20. return defaultdict(self.default_factory, self)
  21. class deque[T]:
  22. _data: list[T]
  23. _head: int
  24. _tail: int
  25. _capacity: int
  26. def __init__(self, iterable: Iterable[T] = None):
  27. self._data = [None] * 8 # type: ignore
  28. self._head = 0
  29. self._tail = 0
  30. self._capacity = len(self._data)
  31. if iterable is not None:
  32. self.extend(iterable)
  33. def __resize_2x(self):
  34. backup = list(self)
  35. self._capacity *= 2
  36. self._head = 0
  37. self._tail = len(backup)
  38. self._data.clear()
  39. self._data.extend(backup)
  40. self._data.extend([None] * (self._capacity - len(backup)))
  41. def append(self, x: T):
  42. self._data[self._tail] = x
  43. self._tail = (self._tail + 1) % self._capacity
  44. if (self._tail + 1) % self._capacity == self._head:
  45. self.__resize_2x()
  46. def appendleft(self, x: T):
  47. self._head = (self._head - 1) % self._capacity
  48. self._data[self._head] = x
  49. if (self._tail + 1) % self._capacity == self._head:
  50. self.__resize_2x()
  51. def copy(self):
  52. return deque(self)
  53. def count(self, x: T) -> int:
  54. n = 0
  55. for item in self:
  56. if item == x:
  57. n += 1
  58. return n
  59. def extend(self, iterable: Iterable[T]):
  60. for x in iterable:
  61. self.append(x)
  62. def extendleft(self, iterable: Iterable[T]):
  63. for x in iterable:
  64. self.appendleft(x)
  65. def pop(self) -> T:
  66. if self._head == self._tail:
  67. raise IndexError("pop from an empty deque")
  68. self._tail = (self._tail - 1) % self._capacity
  69. return self._data[self._tail]
  70. def popleft(self) -> T:
  71. if self._head == self._tail:
  72. raise IndexError("pop from an empty deque")
  73. x = self._data[self._head]
  74. self._head = (self._head + 1) % self._capacity
  75. return x
  76. def clear(self):
  77. i = self._head
  78. while i != self._tail:
  79. self._data[i] = None # type: ignore
  80. i = (i + 1) % self._capacity
  81. self._head = 0
  82. self._tail = 0
  83. def rotate(self, n: int = 1):
  84. if len(self) == 0:
  85. return
  86. if n > 0:
  87. n = n % len(self)
  88. for _ in range(n):
  89. self.appendleft(self.pop())
  90. elif n < 0:
  91. n = -n % len(self)
  92. for _ in range(n):
  93. self.append(self.popleft())
  94. def __len__(self) -> int:
  95. return (self._tail - self._head) % self._capacity
  96. def __contains__(self, x: object) -> bool:
  97. for item in self:
  98. if item == x:
  99. return True
  100. return False
  101. def __iter__(self):
  102. i = self._head
  103. while i != self._tail:
  104. yield self._data[i]
  105. i = (i + 1) % self._capacity
  106. def __eq__(self, other: object) -> bool:
  107. if not isinstance(other, deque):
  108. return NotImplemented
  109. if len(self) != len(other):
  110. return False
  111. for x, y in zip(self, other):
  112. if x != y:
  113. return False
  114. return True
  115. def __ne__(self, other: object) -> bool:
  116. if not isinstance(other, deque):
  117. return NotImplemented
  118. return not self == other
  119. def __repr__(self) -> str:
  120. return f"deque({list(self)!r})"