9d2b7b1af8fdc4cb099311d696965959305e3b2b
1 from abc
import ABCMeta
, abstractmethod
2 from collections
import defaultdict
3 from typing
import (AbstractSet
, Any
, Callable
, Iterable
, Iterator
, Mapping
,
4 MutableSet
, TypeVar
, overload
)
6 from bigint_presentation_code
.type_util
import Self
, final
8 _T_co
= TypeVar("_T_co", covariant
=True)
20 "trailing_zero_count",
25 class _InternedMeta(ABCMeta
):
26 def __call__(self
, *args
: Any
, **kwds
: Any
) -> Any
:
27 return super().__call
__(*args
, **kwds
)._Interned
__intern
()
30 class Interned(metaclass
=_InternedMeta
):
31 def __init_intern(self
):
32 # type: (Self) -> Self
34 old_hash
= cls
.__hash
__
35 old_hash
= getattr(old_hash
, "_Interned__old_hash", old_hash
)
37 old_eq
= getattr(old_eq
, "_Interned__old_eq", old_eq
)
41 return self
._Interned
__hash
# type: ignore
42 __hash__
._Interned
__old
_hash
= old_hash
# type: ignore
43 cls
.__hash
__ = __hash__
45 def __eq__(self
, # type: Self
47 *, __eq
=old_eq
, # type: Callable[[Self, Any], bool]
50 if self
.__class
__ is __other
.__class
__:
51 return self
is __other
52 return __eq(self
, __other
)
53 __eq__
._Interned
__old
_eq
= old_eq
# type: ignore
56 table
= defaultdict(list) # type: dict[int, list[Self]]
58 def __intern(self
, # type: Self
59 *, __hash
=old_hash
, # type: Callable[[Self], int]
60 __eq
=old_eq
, # type: Callable[[Self, Any], bool]
61 __table
=table
, # type: dict[int, list[Self]]
62 __NotImplemented
=NotImplemented, # type: Any
69 if v
is not __NotImplemented
and v
:
71 self
.__dict
__["_Interned__hash"] = h
74 cls
._Interned
__intern
= __intern
77 _Interned__intern
= __init_intern
80 class OFSet(AbstractSet
[_T_co
], Interned
):
81 """ ordered frozen set """
82 __slots__
= "__items", "__dict__", "__weakref__"
84 def __init__(self
, items
=()):
85 # type: (Iterable[_T_co]) -> None
87 if isinstance(items
, OFSet
):
88 self
.__items
= items
.__items
90 self
.__items
= {v
: None for v
in items
}
92 def __contains__(self
, x
):
94 return x
in self
.__items
97 # type: () -> Iterator[_T_co]
98 return iter(self
.__items
)
102 return len(self
.__items
)
112 return f
"OFSet({list(self)})"
115 class OSet(MutableSet
[_T
]):
116 """ ordered mutable set """
117 __slots__
= "__items", "__dict__"
119 def __init__(self
, items
=()):
120 # type: (Iterable[_T]) -> None
122 self
.__items
= {v
: None for v
in items
}
124 def __contains__(self
, x
):
125 # type: (Any) -> bool
126 return x
in self
.__items
129 # type: () -> Iterator[_T]
130 return iter(self
.__items
)
134 return len(self
.__items
)
136 def add(self
, value
):
138 self
.__items
[value
] = None
140 def discard(self
, value
):
142 self
.__items
.pop(value
, None)
148 return f
"OSet({list(self)})"
151 class FMap(Mapping
[_T
, _T_co
], Interned
):
152 """ordered frozen hashable mapping"""
153 __slots__
= "__items", "__hash", "__dict__", "__weakref__"
156 def __init__(self
, items
):
157 # type: (Mapping[_T, _T_co]) -> None
161 def __init__(self
, items
):
162 # type: (Iterable[tuple[_T, _T_co]]) -> None
170 def __init__(self
, items
=()):
171 # type: (Mapping[_T, _T_co] | Iterable[tuple[_T, _T_co]]) -> None
173 self
.__items
= dict(items
) # type: dict[_T, _T_co]
174 self
.__hash
= None # type: None | int
176 def __getitem__(self
, item
):
177 # type: (_T) -> _T_co
178 return self
.__items
[item
]
181 # type: () -> Iterator[_T]
182 return iter(self
.__items
)
186 return len(self
.__items
)
188 def __eq__(self
, other
):
189 # type: (FMap[Any, Any] | Any) -> bool
190 if isinstance(other
, FMap
):
191 return self
.__items
== other
.__items
192 return super().__eq
__(other
)
196 if self
.__hash
is None:
197 self
.__hash
= hash(frozenset(self
.items()))
202 return f
"FMap({self.__items})"
205 def trailing_zero_count(v
, default
=-1):
206 # type: (int, int) -> int
207 without_bit
= v
& (v
- 1) # clear lowest set bit
208 bit
= v
& ~without_bit
# extract lowest set bit
209 return top_set_bit_index(bit
, default
)
212 def top_set_bit_index(v
, default
=-1):
213 # type: (int, int) -> int
216 return v
.bit_length() - 1
220 # added in cpython 3.10
221 bit_count
= int.bit_count
# type: ignore
222 except AttributeError:
225 """returns the number of 1 bits in the absolute value of the input"""
226 return bin(abs(v
)).count('1')
229 class BaseBitSet(AbstractSet
[int]):
230 __slots__
= "__bits", "__dict__", "__weakref__"
239 def _from_bits(cls
, bits
):
240 # type: (int) -> Self
241 return cls(bits
=bits
)
243 def __init__(self
, items
=(), bits
=0):
244 # type: (Iterable[int], int) -> None
246 if isinstance(items
, BaseBitSet
):
251 raise ValueError("can't store negative integers")
254 raise ValueError("can't store an infinite set")
263 def bits(self
, bits
):
264 # type: (int) -> None
266 raise AttributeError("can't write to frozen bitset's bits")
268 raise ValueError("can't store an infinite set")
271 def __contains__(self
, x
):
272 # type: (Any) -> bool
273 if isinstance(x
, int) and x
>= 0:
274 return (1 << x
) & self
.bits
!= 0
278 # type: () -> Iterator[int]
281 index
= trailing_zero_count(bits
)
285 def __reversed__(self
):
286 # type: () -> Iterator[int]
289 index
= top_set_bit_index(bits
)
295 return bit_count(self
.bits
)
300 return f
"{self.__class__.__name__}()"
304 return f
"{self.__class__.__name__}({v})"
305 ranges
= [] # type: list[range]
308 if len(ranges
) != 0 and ranges
[-1].stop
== i
:
310 ranges
[-1].start
, i
+ ranges
[-1].step
, ranges
[-1].step
)
311 elif len(ranges
) != 0 and len(ranges
[-1]) == 1:
312 start
= ranges
[-1][0]
315 ranges
[-1] = range(start
, stop
, step
)
316 elif len(ranges
) != 0 and len(ranges
[-1]) == 2:
317 single
= ranges
[-1][0]
318 start
= ranges
[-1][1]
319 ranges
[-1] = range(single
, single
+ 1)
322 ranges
.append(range(start
, stop
, step
))
324 ranges
.append(range(i
, i
+ 1))
325 if len(ranges
) > MAX_RANGES
:
328 return f
"{self.__class__.__name__}({ranges[0]})"
329 if len(ranges
) <= MAX_RANGES
:
330 range_strs
= [] # type: list[str]
333 range_strs
.append(str(r
[0]))
335 range_strs
.append(f
"*{r}")
336 ranges_str
= ", ".join(range_strs
)
337 return f
"{self.__class__.__name__}([{ranges_str}])"
338 if self
.bits
> 0xFFFFFFFF and len_self
< 10:
340 return f
"{self.__class__.__name__}({v})"
341 return f
"{self.__class__.__name__}(bits={hex(self.bits)})"
343 def __eq__(self
, other
):
344 # type: (Any) -> bool
345 if not isinstance(other
, BaseBitSet
):
346 return super().__eq
__(other
)
347 return self
.bits
== other
.bits
349 def __and__(self
, other
):
350 # type: (Iterable[Any]) -> Self
351 if isinstance(other
, BaseBitSet
):
352 return self
._from
_bits
(self
.bits
& other
.bits
)
355 if isinstance(item
, int) and item
>= 0:
357 return self
._from
_bits
(self
.bits
& bits
)
361 def __or__(self
, other
):
362 # type: (Iterable[Any]) -> Self
363 if isinstance(other
, BaseBitSet
):
364 return self
._from
_bits
(self
.bits | other
.bits
)
367 if isinstance(item
, int) and item
>= 0:
369 return self
._from
_bits
(bits
)
373 def __xor__(self
, other
):
374 # type: (Iterable[Any]) -> Self
375 if isinstance(other
, BaseBitSet
):
376 return self
._from
_bits
(self
.bits ^ other
.bits
)
379 if isinstance(item
, int) and item
>= 0:
381 return self
._from
_bits
(bits
)
385 def __sub__(self
, other
):
386 # type: (Iterable[Any]) -> Self
387 if isinstance(other
, BaseBitSet
):
388 return self
._from
_bits
(self
.bits
& ~other
.bits
)
391 if isinstance(item
, int) and item
>= 0:
393 return self
._from
_bits
(bits
)
395 def __rsub__(self
, other
):
396 # type: (Iterable[Any]) -> Self
397 if isinstance(other
, BaseBitSet
):
398 return self
._from
_bits
(~self
.bits
& other
.bits
)
401 if isinstance(item
, int) and item
>= 0:
403 return self
._from
_bits
(~self
.bits
& bits
)
405 def isdisjoint(self
, other
):
406 # type: (Iterable[Any]) -> bool
407 if isinstance(other
, BaseBitSet
):
408 return self
.bits
& other
.bits
== 0
409 return super().isdisjoint(other
)
412 class BitSet(BaseBitSet
, MutableSet
[int]):
413 """Mutable Bit Set"""
421 def add(self
, value
):
422 # type: (int) -> None
424 raise ValueError("can't store negative integers")
425 self
.bits |
= 1 << value
427 def discard(self
, value
):
428 # type: (int) -> None
430 self
.bits
&= ~
(1 << value
)
436 def __ior__(self
, it
):
437 # type: (AbstractSet[Any]) -> Self
438 if isinstance(it
, BaseBitSet
):
441 return super().__ior
__(it
)
443 def __iand__(self
, it
):
444 # type: (AbstractSet[Any]) -> Self
445 if isinstance(it
, BaseBitSet
):
448 return super().__iand
__(it
)
450 def __ixor__(self
, it
):
451 # type: (AbstractSet[Any]) -> Self
452 if isinstance(it
, BaseBitSet
):
455 return super().__ixor
__(it
)
457 def __isub__(self
, it
):
458 # type: (AbstractSet[Any]) -> Self
459 if isinstance(it
, BaseBitSet
):
460 self
.bits
&= ~it
.bits
462 return super().__isub
__(it
)
465 class FBitSet(BaseBitSet
, Interned
):
476 return super()._hash
()