1# from titan_pylib.data_structures.safe_hash.hash_counter import HashCounter
2# from titan_pylib.data_structures.safe_hash.hash_dict import HashDict
3from typing import Any, Iterator
4from random import Random
5
6
7class HashDict:
8
9 _r = Random()
10 _xor = _r.randrange(10000000, 1000000000)
11
12 def __init__(self) -> None:
13 self._data: dict[int, Any] = {}
14
15 def __setitem__(self, key: int, val: Any) -> None:
16 self._data[key ^ self._xor] = val
17
18 def __getitem__(self, key: int) -> Any:
19 return self._data[key ^ self._xor]
20
21 def __delitem__(self, key: int) -> None:
22 del self._data[key ^ self._xor]
23
24 def __contains__(self, key: int) -> bool:
25 return key ^ self._xor in self._data
26
27 def __len__(self) -> bool:
28 return len(self._data)
29
30 def keys(self) -> Iterator[int]:
31 return (k ^ self._xor for k in self._data.keys())
32
33 def values(self) -> Iterator[Any]:
34 return (v for v in self._data.values())
35
36 def items(self) -> Iterator[tuple[int, Any]]:
37 return ((k ^ self._xor, v) for k, v in self._data.items())
38
39 def __str__(self) -> str:
40 return "{" + ", ".join(f"{k}: {v}" for k, v in self.items()) + "}"
41
42 def __repr__(self):
43 return f"{self.__class__.__name__}({self})"
44from typing import Iterable, Iterator
45
46
47class HashCounter:
48
49 def __init__(self, a: Iterable[int] = []) -> None:
50 self._data = HashDict()
51 for a_ in a:
52 if a_ in self._data:
53 self._data[a_] += 1
54 else:
55 self._data[a_] = 1
56
57 def __iter__(self) -> Iterator[tuple[int, int]]:
58 for k, v in self._data.items():
59 yield k, v
60
61 def __setitem__(self, key: int, val: int) -> None:
62 self._data[key] = val
63
64 def __getitem__(self, key: int) -> int:
65 return self._data[key] if key in self._data else 0
66
67 def __delitem__(self, key: int) -> None:
68 if key in self._data:
69 del self._data[key]
70
71 def __contains__(self, key: int) -> bool:
72 return key in self._data
73
74 def most_common(self) -> list[tuple[int, int]]:
75 return sorted(self._data.items(), key=lambda x: -x[1])
76
77 def keys(self) -> Iterator[int]:
78 return self._data.keys()
79
80 def values(self) -> Iterator[int]:
81 return self._data.values()
82
83 def items(self) -> Iterable[tuple[int, int]]:
84 return self._data.items()
85
86 def __len__(self) -> int:
87 return len(self._data)
88
89 def __str__(self) -> str:
90 return f"{self.__class__.__name__}({str(self._data)})"
91
92 def __repr__(self) -> str:
93 return f"{self.__class__.__name__}({self})"