collections.py 3.9 KB

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