87c6975425dbfd4fdec64df750a0110924c648ee
1 from abc
import ABCMeta
, abstractmethod
2 from typing
import (AbstractSet
, Any
, Iterable
, Iterator
, Mapping
, MutableSet
,
5 from bigint_presentation_code
.type_util
import Self
, final
7 _T_co
= TypeVar("_T_co", covariant
=True)
19 "trailing_zero_count",
24 class InternedMeta(ABCMeta
):
25 def __init__(self
, *args
, **kwargs
):
26 # type: (*Any, **Any) -> None
27 super().__init
__(*args
, **kwargs
)
28 self
.__INTERN
_TABLE
= {} # type: dict[Any, Any]
30 def __intern(self
, value
):
32 value
= self
.__INTERN
_TABLE
.setdefault(value
, value
)
33 if value
.__dict
__.get("_InternedMeta__interned", False):
35 value
.__dict
__["_InternedMeta__interned"] = True
37 value
.__dict
__["__hash__"] = lambda: hash_v
42 if value
.__class
__ is __o
.__class
__:
45 value
.__dict
__["__eq__"] = __eq__
48 def __call__(self
, *args
, **kwargs
):
49 # type: (*Any, **Any) -> Any
50 return self
.__intern
(super().__call
__(*args
, **kwargs
))
53 class OFSet(AbstractSet
[_T_co
], metaclass
=InternedMeta
):
54 """ ordered frozen set """
55 __slots__
= "__items", "__dict__", "__weakref__"
57 def __init__(self
, items
=()):
58 # type: (Iterable[_T_co]) -> None
60 self
.__items
= {v
: None for v
in items
}
62 def __contains__(self
, x
):
64 return x
in self
.__items
67 # type: () -> Iterator[_T_co]
68 return iter(self
.__items
)
72 return len(self
.__items
)
82 return f
"OFSet({list(self)})"
85 class OSet(MutableSet
[_T
]):
86 """ ordered mutable set """
87 __slots__
= "__items", "__dict__"
89 def __init__(self
, items
=()):
90 # type: (Iterable[_T]) -> None
92 self
.__items
= {v
: None for v
in items
}
94 def __contains__(self
, x
):
96 return x
in self
.__items
99 # type: () -> Iterator[_T]
100 return iter(self
.__items
)
104 return len(self
.__items
)
106 def add(self
, value
):
108 self
.__items
[value
] = None
110 def discard(self
, value
):
112 self
.__items
.pop(value
, None)
118 return f
"OSet({list(self)})"
121 class FMap(Mapping
[_T
, _T_co
], metaclass
=InternedMeta
):
122 """ordered frozen hashable mapping"""
123 __slots__
= "__items", "__hash", "__dict__", "__weakref__"
126 def __init__(self
, items
):
127 # type: (Mapping[_T, _T_co]) -> None
131 def __init__(self
, items
):
132 # type: (Iterable[tuple[_T, _T_co]]) -> None
140 def __init__(self
, items
=()):
141 # type: (Mapping[_T, _T_co] | Iterable[tuple[_T, _T_co]]) -> None
143 self
.__items
= dict(items
) # type: dict[_T, _T_co]
144 self
.__hash
= None # type: None | int
146 def __getitem__(self
, item
):
147 # type: (_T) -> _T_co
148 return self
.__items
[item
]
151 # type: () -> Iterator[_T]
152 return iter(self
.__items
)
156 return len(self
.__items
)
158 def __eq__(self
, other
):
159 # type: (FMap[Any, Any] | Any) -> bool
160 if isinstance(other
, FMap
):
161 return self
.__items
== other
.__items
162 return super().__eq
__(other
)
166 if self
.__hash
is None:
167 self
.__hash
= hash(frozenset(self
.items()))
172 return f
"FMap({self.__items})"
175 def trailing_zero_count(v
, default
=-1):
176 # type: (int, int) -> int
177 without_bit
= v
& (v
- 1) # clear lowest set bit
178 bit
= v
& ~without_bit
# extract lowest set bit
179 return top_set_bit_index(bit
, default
)
182 def top_set_bit_index(v
, default
=-1):
183 # type: (int, int) -> int
186 return v
.bit_length() - 1
190 # added in cpython 3.10
191 bit_count
= int.bit_count
# type: ignore
192 except AttributeError:
195 """returns the number of 1 bits in the absolute value of the input"""
196 return bin(abs(v
)).count('1')
199 class BaseBitSet(AbstractSet
[int]):
200 __slots__
= "__bits", "__dict__", "__weakref__"
209 def _from_bits(cls
, bits
):
210 # type: (int) -> Self
211 return cls(bits
=bits
)
213 def __init__(self
, items
=(), bits
=0):
214 # type: (Iterable[int], int) -> None
216 if isinstance(items
, BaseBitSet
):
221 raise ValueError("can't store negative integers")
224 raise ValueError("can't store an infinite set")
233 def bits(self
, bits
):
234 # type: (int) -> None
236 raise AttributeError("can't write to frozen bitset's bits")
238 raise ValueError("can't store an infinite set")
241 def __contains__(self
, x
):
242 # type: (Any) -> bool
243 if isinstance(x
, int) and x
>= 0:
244 return (1 << x
) & self
.bits
!= 0
248 # type: () -> Iterator[int]
251 index
= trailing_zero_count(bits
)
255 def __reversed__(self
):
256 # type: () -> Iterator[int]
259 index
= top_set_bit_index(bits
)
265 return bit_count(self
.bits
)
270 return f
"{self.__class__.__name__}()"
274 return f
"{self.__class__.__name__}({v})"
275 ranges
= [] # type: list[range]
278 if len(ranges
) != 0 and ranges
[-1].stop
== i
:
280 ranges
[-1].start
, i
+ ranges
[-1].step
, ranges
[-1].step
)
281 elif len(ranges
) != 0 and len(ranges
[-1]) == 1:
282 start
= ranges
[-1][0]
285 ranges
[-1] = range(start
, stop
, step
)
286 elif len(ranges
) != 0 and len(ranges
[-1]) == 2:
287 single
= ranges
[-1][0]
288 start
= ranges
[-1][1]
289 ranges
[-1] = range(single
, single
+ 1)
292 ranges
.append(range(start
, stop
, step
))
294 ranges
.append(range(i
, i
+ 1))
295 if len(ranges
) > MAX_RANGES
:
298 return f
"{self.__class__.__name__}({ranges[0]})"
299 if len(ranges
) <= MAX_RANGES
:
300 range_strs
= [] # type: list[str]
303 range_strs
.append(str(r
[0]))
305 range_strs
.append(f
"*{r}")
306 ranges_str
= ", ".join(range_strs
)
307 return f
"{self.__class__.__name__}([{ranges_str}])"
308 if self
.bits
> 0xFFFFFFFF and len_self
< 10:
310 return f
"{self.__class__.__name__}({v})"
311 return f
"{self.__class__.__name__}(bits={hex(self.bits)})"
313 def __eq__(self
, other
):
314 # type: (Any) -> bool
315 if not isinstance(other
, BaseBitSet
):
316 return super().__eq
__(other
)
317 return self
.bits
== other
.bits
319 def __and__(self
, other
):
320 # type: (Iterable[Any]) -> Self
321 if isinstance(other
, BaseBitSet
):
322 return self
._from
_bits
(self
.bits
& other
.bits
)
325 if isinstance(item
, int) and item
>= 0:
327 return self
._from
_bits
(self
.bits
& bits
)
331 def __or__(self
, other
):
332 # type: (Iterable[Any]) -> Self
333 if isinstance(other
, BaseBitSet
):
334 return self
._from
_bits
(self
.bits | other
.bits
)
337 if isinstance(item
, int) and item
>= 0:
339 return self
._from
_bits
(bits
)
343 def __xor__(self
, other
):
344 # type: (Iterable[Any]) -> Self
345 if isinstance(other
, BaseBitSet
):
346 return self
._from
_bits
(self
.bits ^ other
.bits
)
349 if isinstance(item
, int) and item
>= 0:
351 return self
._from
_bits
(bits
)
355 def __sub__(self
, other
):
356 # type: (Iterable[Any]) -> Self
357 if isinstance(other
, BaseBitSet
):
358 return self
._from
_bits
(self
.bits
& ~other
.bits
)
361 if isinstance(item
, int) and item
>= 0:
363 return self
._from
_bits
(bits
)
365 def __rsub__(self
, other
):
366 # type: (Iterable[Any]) -> Self
367 if isinstance(other
, BaseBitSet
):
368 return self
._from
_bits
(~self
.bits
& other
.bits
)
371 if isinstance(item
, int) and item
>= 0:
373 return self
._from
_bits
(~self
.bits
& bits
)
375 def isdisjoint(self
, other
):
376 # type: (Iterable[Any]) -> bool
377 if isinstance(other
, BaseBitSet
):
378 return self
.bits
& other
.bits
== 0
379 return super().isdisjoint(other
)
382 class BitSet(BaseBitSet
, MutableSet
[int]):
383 """Mutable Bit Set"""
391 def add(self
, value
):
392 # type: (int) -> None
394 raise ValueError("can't store negative integers")
395 self
.bits |
= 1 << value
397 def discard(self
, value
):
398 # type: (int) -> None
400 self
.bits
&= ~
(1 << value
)
406 def __ior__(self
, it
):
407 # type: (AbstractSet[Any]) -> Self
408 if isinstance(it
, BaseBitSet
):
411 return super().__ior
__(it
)
413 def __iand__(self
, it
):
414 # type: (AbstractSet[Any]) -> Self
415 if isinstance(it
, BaseBitSet
):
418 return super().__iand
__(it
)
420 def __ixor__(self
, it
):
421 # type: (AbstractSet[Any]) -> Self
422 if isinstance(it
, BaseBitSet
):
425 return super().__ixor
__(it
)
427 def __isub__(self
, it
):
428 # type: (AbstractSet[Any]) -> Self
429 if isinstance(it
, BaseBitSet
):
430 self
.bits
&= ~it
.bits
432 return super().__isub
__(it
)
435 class FBitSet(BaseBitSet
, metaclass
=InternedMeta
):
446 return super()._hash
()