757f267ecdfabcc923980e3d863666b5c55d0305
1 from abc
import 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",
23 class OFSet(AbstractSet
[_T_co
]):
24 """ ordered frozen set """
25 __slots__
= "__items",
27 def __init__(self
, items
=()):
28 # type: (Iterable[_T_co]) -> None
30 self
.__items
= {v
: None for v
in items
}
32 def __contains__(self
, x
):
34 return x
in self
.__items
37 # type: () -> Iterator[_T_co]
38 return iter(self
.__items
)
42 return len(self
.__items
)
52 return f
"OFSet({list(self)})"
55 class OSet(MutableSet
[_T
]):
56 """ ordered mutable set """
57 __slots__
= "__items",
59 def __init__(self
, items
=()):
60 # type: (Iterable[_T]) -> None
62 self
.__items
= {v
: None for v
in items
}
64 def __contains__(self
, x
):
66 return x
in self
.__items
69 # type: () -> Iterator[_T]
70 return iter(self
.__items
)
74 return len(self
.__items
)
78 self
.__items
[value
] = None
80 def discard(self
, value
):
82 self
.__items
.pop(value
, None)
88 return f
"OSet({list(self)})"
91 class FMap(Mapping
[_T
, _T_co
]):
92 """ordered frozen hashable mapping"""
93 __slots__
= "__items", "__hash"
96 def __init__(self
, items
):
97 # type: (Mapping[_T, _T_co]) -> None
101 def __init__(self
, items
):
102 # type: (Iterable[tuple[_T, _T_co]]) -> None
110 def __init__(self
, items
=()):
111 # type: (Mapping[_T, _T_co] | Iterable[tuple[_T, _T_co]]) -> None
113 self
.__items
= dict(items
) # type: dict[_T, _T_co]
114 self
.__hash
= None # type: None | int
116 def __getitem__(self
, item
):
117 # type: (_T) -> _T_co
118 return self
.__items
[item
]
121 # type: () -> Iterator[_T]
122 return iter(self
.__items
)
126 return len(self
.__items
)
128 def __eq__(self
, other
):
129 # type: (FMap[Any, Any] | Any) -> bool
130 if isinstance(other
, FMap
):
131 return self
.__items
== other
.__items
132 return super().__eq
__(other
)
136 if self
.__hash
is None:
137 self
.__hash
= hash(frozenset(self
.items()))
142 return f
"FMap({self.__items})"
145 def trailing_zero_count(v
, default
=-1):
146 # type: (int, int) -> int
147 without_bit
= v
& (v
- 1) # clear lowest set bit
148 bit
= v
& ~without_bit
# extract lowest set bit
149 return top_set_bit_index(bit
, default
)
152 def top_set_bit_index(v
, default
=-1):
153 # type: (int, int) -> int
156 return v
.bit_length() - 1
160 # added in cpython 3.10
161 bit_count
= int.bit_count
# type: ignore
162 except AttributeError:
165 """returns the number of 1 bits in the absolute value of the input"""
166 return bin(abs(v
)).count('1')
169 class BaseBitSet(AbstractSet
[int]):
170 __slots__
= "__bits",
179 def _from_bits(cls
, bits
):
180 # type: (int) -> Self
181 return cls(bits
=bits
)
183 def __init__(self
, items
=(), bits
=0):
184 # type: (Iterable[int], int) -> None
186 if isinstance(items
, BaseBitSet
):
191 raise ValueError("can't store negative integers")
194 raise ValueError("can't store an infinite set")
203 def bits(self
, bits
):
204 # type: (int) -> None
206 raise AttributeError("can't write to frozen bitset's bits")
208 raise ValueError("can't store an infinite set")
211 def __contains__(self
, x
):
212 # type: (Any) -> bool
213 if isinstance(x
, int) and x
>= 0:
214 return (1 << x
) & self
.bits
!= 0
218 # type: () -> Iterator[int]
221 index
= trailing_zero_count(bits
)
225 def __reversed__(self
):
226 # type: () -> Iterator[int]
229 index
= top_set_bit_index(bits
)
235 return bit_count(self
.bits
)
240 return f
"{self.__class__.__name__}()"
244 return f
"{self.__class__.__name__}({v})"
245 ranges
= [] # type: list[range]
248 if len(ranges
) != 0 and ranges
[-1].stop
== i
:
250 ranges
[-1].start
, i
+ ranges
[-1].step
, ranges
[-1].step
)
251 elif len(ranges
) != 0 and len(ranges
[-1]) == 1:
252 start
= ranges
[-1][0]
255 ranges
[-1] = range(start
, stop
, step
)
256 elif len(ranges
) != 0 and len(ranges
[-1]) == 2:
257 single
= ranges
[-1][0]
258 start
= ranges
[-1][1]
259 ranges
[-1] = range(single
, single
+ 1)
262 ranges
.append(range(start
, stop
, step
))
264 ranges
.append(range(i
, i
+ 1))
265 if len(ranges
) > MAX_RANGES
:
268 return f
"{self.__class__.__name__}({ranges[0]})"
269 if len(ranges
) <= MAX_RANGES
:
270 range_strs
= [] # type: list[str]
273 range_strs
.append(str(r
[0]))
275 range_strs
.append(f
"*{r}")
276 ranges_str
= ", ".join(range_strs
)
277 return f
"{self.__class__.__name__}([{ranges_str}])"
278 if self
.bits
> 0xFFFFFFFF and len_self
< 10:
280 return f
"{self.__class__.__name__}({v})"
281 return f
"{self.__class__.__name__}(bits={hex(self.bits)})"
283 def __eq__(self
, other
):
284 # type: (Any) -> bool
285 if not isinstance(other
, BaseBitSet
):
286 return super().__eq
__(other
)
287 return self
.bits
== other
.bits
289 def __and__(self
, other
):
290 # type: (Iterable[Any]) -> Self
291 if isinstance(other
, BaseBitSet
):
292 return self
._from
_bits
(self
.bits
& other
.bits
)
295 if isinstance(item
, int) and item
>= 0:
297 return self
._from
_bits
(self
.bits
& bits
)
301 def __or__(self
, other
):
302 # type: (Iterable[Any]) -> Self
303 if isinstance(other
, BaseBitSet
):
304 return self
._from
_bits
(self
.bits | other
.bits
)
307 if isinstance(item
, int) and item
>= 0:
309 return self
._from
_bits
(bits
)
313 def __xor__(self
, other
):
314 # type: (Iterable[Any]) -> Self
315 if isinstance(other
, BaseBitSet
):
316 return self
._from
_bits
(self
.bits ^ other
.bits
)
319 if isinstance(item
, int) and item
>= 0:
321 return self
._from
_bits
(bits
)
325 def __sub__(self
, other
):
326 # type: (Iterable[Any]) -> Self
327 if isinstance(other
, BaseBitSet
):
328 return self
._from
_bits
(self
.bits
& ~other
.bits
)
331 if isinstance(item
, int) and item
>= 0:
333 return self
._from
_bits
(bits
)
335 def __rsub__(self
, other
):
336 # type: (Iterable[Any]) -> Self
337 if isinstance(other
, BaseBitSet
):
338 return self
._from
_bits
(~self
.bits
& other
.bits
)
341 if isinstance(item
, int) and item
>= 0:
343 return self
._from
_bits
(~self
.bits
& bits
)
345 def isdisjoint(self
, other
):
346 # type: (Iterable[Any]) -> bool
347 if isinstance(other
, BaseBitSet
):
348 return self
.bits
& other
.bits
== 0
349 return super().isdisjoint(other
)
352 class BitSet(BaseBitSet
, MutableSet
[int]):
353 """Mutable Bit Set"""
361 def add(self
, value
):
362 # type: (int) -> None
364 raise ValueError("can't store negative integers")
365 self
.bits |
= 1 << value
367 def discard(self
, value
):
368 # type: (int) -> None
370 self
.bits
&= ~
(1 << value
)
376 def __ior__(self
, it
):
377 # type: (AbstractSet[Any]) -> Self
378 if isinstance(it
, BaseBitSet
):
381 return super().__ior
__(it
)
383 def __iand__(self
, it
):
384 # type: (AbstractSet[Any]) -> Self
385 if isinstance(it
, BaseBitSet
):
388 return super().__iand
__(it
)
390 def __ixor__(self
, it
):
391 # type: (AbstractSet[Any]) -> Self
392 if isinstance(it
, BaseBitSet
):
395 return super().__ixor
__(it
)
397 def __isub__(self
, it
):
398 # type: (AbstractSet[Any]) -> Self
399 if isinstance(it
, BaseBitSet
):
400 self
.bits
&= ~it
.bits
402 return super().__isub
__(it
)
405 class FBitSet(BaseBitSet
):
416 return super()._hash
()