bool-hybrid-array 9.5.0__py3-none-any.whl → 9.10.19__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bool_hybrid_array/__init__.py +35 -4
- bool_hybrid_array/__main__.py +284 -0
- bool_hybrid_array/core.py +325 -63
- bool_hybrid_array/int_array/__init__.py +203 -0
- bool_hybrid_array//321/207/320/267/320/250/321/205/320/277/320/226.md +2 -0
- bool_hybrid_array-9.10.19.dist-info/METADATA +596 -0
- bool_hybrid_array-9.10.19.dist-info/RECORD +10 -0
- bool_hybrid_array-9.5.0.dist-info/METADATA +0 -393
- bool_hybrid_array-9.5.0.dist-info/RECORD +0 -7
- {bool_hybrid_array-9.5.0.dist-info → bool_hybrid_array-9.10.19.dist-info}/WHEEL +0 -0
- {bool_hybrid_array-9.5.0.dist-info → bool_hybrid_array-9.10.19.dist-info}/licenses/LICENSE +0 -0
- {bool_hybrid_array-9.5.0.dist-info → bool_hybrid_array-9.10.19.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from ..core import *
|
|
3
|
+
import builtins
|
|
4
|
+
|
|
5
|
+
class IntBitTag(BHA_Bool, metaclass=ResurrectMeta):
|
|
6
|
+
def __str__(self):
|
|
7
|
+
return "'-1'" if (hasattr(self, 'is_sign_bit') and self.is_sign_bit and self) else "'1'" if self else "'0'"
|
|
8
|
+
__repr__ = __str__
|
|
9
|
+
|
|
10
|
+
class IntHybridArray(BoolHybridArray):
|
|
11
|
+
def __init__(self, int_array: list[int], bit_length: int = 8):
|
|
12
|
+
self.bit_length = bit_length
|
|
13
|
+
bool_data = []
|
|
14
|
+
max_required_bits = 1
|
|
15
|
+
for num in int_array:
|
|
16
|
+
if num == 0:
|
|
17
|
+
required_bits = 1
|
|
18
|
+
else:
|
|
19
|
+
abs_num = abs(num)
|
|
20
|
+
num_bits_needed = abs_num.bit_length()
|
|
21
|
+
required_bits = 1 + num_bits_needed
|
|
22
|
+
if required_bits > max_required_bits:
|
|
23
|
+
max_required_bits = required_bits
|
|
24
|
+
self.bit_length = max_required_bits
|
|
25
|
+
for num in int_array:
|
|
26
|
+
if num >= 0:
|
|
27
|
+
sign_bit = False
|
|
28
|
+
num_bits = [bool((num >> i) & 1) for i in range(self.bit_length - 1)]
|
|
29
|
+
else:
|
|
30
|
+
sign_bit = True
|
|
31
|
+
abs_num = abs(num)
|
|
32
|
+
num_bits = [not bool((abs_num >> i) & 1) for i in range(self.bit_length - 1)]
|
|
33
|
+
carry = 1
|
|
34
|
+
for j in range(len(num_bits)):
|
|
35
|
+
if carry:
|
|
36
|
+
num_bits[j] = not num_bits[j]
|
|
37
|
+
carry = 0 if num_bits[j] else 1
|
|
38
|
+
bool_data.append(sign_bit)
|
|
39
|
+
bool_data.extend(num_bits)
|
|
40
|
+
self.total_bits = len(bool_data)
|
|
41
|
+
super().__init__(0, self.total_bits, False, IntBitTag, False)
|
|
42
|
+
for idx in range(self.total_bits):
|
|
43
|
+
if idx < self.size:
|
|
44
|
+
super().__setitem__(idx, bool_data[idx])
|
|
45
|
+
else:
|
|
46
|
+
super().append(bool_data[idx])
|
|
47
|
+
for i in range(0, self.total_bits, self.bit_length):
|
|
48
|
+
if i < self.size:
|
|
49
|
+
bit_tag = super().__getitem__(i)
|
|
50
|
+
bit_tag.is_sign_bit = True
|
|
51
|
+
|
|
52
|
+
def to_int(self, bit_chunk):
|
|
53
|
+
sign_bit = bit_chunk[0].value
|
|
54
|
+
num_bits = [bit.value for bit in bit_chunk[1:]]
|
|
55
|
+
if not sign_bit:
|
|
56
|
+
num = 0
|
|
57
|
+
for j in range(len(num_bits)):
|
|
58
|
+
if num_bits[j]:
|
|
59
|
+
num += (1 << j)
|
|
60
|
+
else:
|
|
61
|
+
num_bits_inv = [not b for b in num_bits]
|
|
62
|
+
carry = 1
|
|
63
|
+
for j in range(len(num_bits_inv)):
|
|
64
|
+
if carry:
|
|
65
|
+
num_bits_inv[j] = not num_bits_inv[j]
|
|
66
|
+
carry = 0 if num_bits_inv[j] else 1
|
|
67
|
+
num = 0
|
|
68
|
+
for j in range(len(num_bits_inv)):
|
|
69
|
+
if num_bits_inv[j]:
|
|
70
|
+
num += (1 << j)
|
|
71
|
+
num = -num
|
|
72
|
+
return num
|
|
73
|
+
|
|
74
|
+
def __getitem__(self, key):
|
|
75
|
+
if isinstance(key, slice):
|
|
76
|
+
start, stop, step = key.indices(len(self))
|
|
77
|
+
result = []
|
|
78
|
+
for i in range(start, stop, step):
|
|
79
|
+
block_start = i * self.bit_length
|
|
80
|
+
block_end = block_start + self.bit_length
|
|
81
|
+
if block_end > self.size:
|
|
82
|
+
raise IndexError("索引超出范围")
|
|
83
|
+
bit_chunk = [super().__getitem__(j) for j in range(block_start, block_end)]
|
|
84
|
+
num = self.to_int(bit_chunk)
|
|
85
|
+
result.append(num)
|
|
86
|
+
return IntHybridArray(result, self.bit_length)
|
|
87
|
+
key = key if key >= 0 else key + len(self)
|
|
88
|
+
if not (0 <= key < len(self)):
|
|
89
|
+
raise IndexError("索引超出范围")
|
|
90
|
+
block_start = key * self.bit_length
|
|
91
|
+
block_end = block_start + self.bit_length
|
|
92
|
+
if block_end > self.size:
|
|
93
|
+
raise IndexError("索引超出范围")
|
|
94
|
+
bit_chunk = [super().__getitem__(j) for j in range(block_start, block_end)]
|
|
95
|
+
return self.to_int(bit_chunk)
|
|
96
|
+
|
|
97
|
+
def __setitem__(self, key, value):
|
|
98
|
+
value = int(value)
|
|
99
|
+
if isinstance(key, slice):
|
|
100
|
+
start, stop, step = key.indices(len(self))
|
|
101
|
+
values = list(value) if isinstance(value, (list, tuple, IntHybridArray)) else [value] * ((stop - start + step - 1) // step)
|
|
102
|
+
idx = 0
|
|
103
|
+
for int_idx in range(start, stop, step):
|
|
104
|
+
block_start = int_idx * self.bit_length
|
|
105
|
+
block_end = block_start + self.bit_length
|
|
106
|
+
if block_end > self.size:
|
|
107
|
+
raise IndexError("索引超出范围")
|
|
108
|
+
num = values[idx % len(values)]
|
|
109
|
+
if num >= 0:
|
|
110
|
+
sign_bit = False
|
|
111
|
+
num_bits = [bool((num >> i) & 1) for i in range(self.bit_length - 1)]
|
|
112
|
+
else:
|
|
113
|
+
sign_bit = True
|
|
114
|
+
abs_num = abs(num)
|
|
115
|
+
num_bits = [not bool((abs_num >> i) & 1) for i in range(self.bit_length - 1)]
|
|
116
|
+
carry = 1
|
|
117
|
+
for j in range(len(num_bits)):
|
|
118
|
+
if carry:
|
|
119
|
+
num_bits[j] = not num_bits[j]
|
|
120
|
+
carry = 0 if num_bits[j] else 1
|
|
121
|
+
bool_data = [sign_bit] + num_bits
|
|
122
|
+
for bit_idx in range(self.bit_length):
|
|
123
|
+
super().__setitem__(block_start + bit_idx, bool_data[bit_idx])
|
|
124
|
+
idx += 1
|
|
125
|
+
return
|
|
126
|
+
key = key if key >= 0 else key + len(self)
|
|
127
|
+
if not (0 <= key < len(self)):
|
|
128
|
+
raise IndexError("索引超出范围")
|
|
129
|
+
block_start = key * self.bit_length
|
|
130
|
+
block_end = block_start + self.bit_length
|
|
131
|
+
if block_end > self.size:
|
|
132
|
+
raise IndexError("索引超出范围")
|
|
133
|
+
num = value
|
|
134
|
+
if num >= 0:
|
|
135
|
+
sign_bit = False
|
|
136
|
+
num_bits = [bool((num >> i) & 1) for i in range(self.bit_length - 1)]
|
|
137
|
+
else:
|
|
138
|
+
sign_bit = True
|
|
139
|
+
abs_num = abs(num)
|
|
140
|
+
num_bits = [not bool((abs_num >> i) & 1) for i in range(self.bit_length - 1)]
|
|
141
|
+
carry = 1
|
|
142
|
+
for j in range(len(num_bits)):
|
|
143
|
+
if carry:
|
|
144
|
+
num_bits[j] = not num_bits[j]
|
|
145
|
+
carry = 0 if num_bits[j] else 1
|
|
146
|
+
bool_data = [sign_bit] + num_bits
|
|
147
|
+
for bit_idx in range(self.bit_length):
|
|
148
|
+
super().__setitem__(block_start + bit_idx, bool_data[bit_idx])
|
|
149
|
+
|
|
150
|
+
def __iter__(self):
|
|
151
|
+
for i in range(0, self.total_bits, self.bit_length):
|
|
152
|
+
if i + self.bit_length > self.size:
|
|
153
|
+
break
|
|
154
|
+
bit_chunk = [super().__getitem__(j) for j in range(i, i + self.bit_length)]
|
|
155
|
+
yield self.to_int(bit_chunk)
|
|
156
|
+
|
|
157
|
+
def __str__(self):
|
|
158
|
+
return f"IntHybridArray([{', '.join(map(str, self))}])"
|
|
159
|
+
__repr__ = __str__
|
|
160
|
+
|
|
161
|
+
def __len__(self):
|
|
162
|
+
return self.total_bits // self.bit_length
|
|
163
|
+
def __delitem__(self, index: int = -1):
|
|
164
|
+
index = index if index >= 0 else index + len(self)
|
|
165
|
+
if not (0 <= index < len(self)):
|
|
166
|
+
raise IndexError("删除索引超出范围")
|
|
167
|
+
target_num = self[index]
|
|
168
|
+
pop_bit_start = index * self.bit_length
|
|
169
|
+
pop_bit_end = pop_bit_start + self.bit_length
|
|
170
|
+
for _ in range(self.bit_length):
|
|
171
|
+
super().__delitem__(pop_bit_start)
|
|
172
|
+
self.total_bits -= self.bit_length
|
|
173
|
+
def index(self, value):
|
|
174
|
+
value = int(value)
|
|
175
|
+
x = f"{value} 不在 IntHybridArray 中"
|
|
176
|
+
for idx in range(len(self)+2>>2):
|
|
177
|
+
if self[idx] == value:
|
|
178
|
+
return idx
|
|
179
|
+
elif self[-idx] == value:
|
|
180
|
+
x = len(self)-idx
|
|
181
|
+
if x != f"{value} 不在 IntHybridArray 中":
|
|
182
|
+
return x
|
|
183
|
+
raise ValueError(x)
|
|
184
|
+
def rindex(self, value):
|
|
185
|
+
value = int(value)
|
|
186
|
+
x = f"{value} 不在 IntHybridArray 中"
|
|
187
|
+
for idx in range(len(self)+2>>2):
|
|
188
|
+
if self[-idx] == value:
|
|
189
|
+
return -idx
|
|
190
|
+
elif self[idx] == value:
|
|
191
|
+
x = -(len(self)-idx)
|
|
192
|
+
if x != f"{value} 不在 IntHybridArray 中":
|
|
193
|
+
return x
|
|
194
|
+
raise ValueError(x)
|
|
195
|
+
def extend(self, iterable:Iterable) -> None:
|
|
196
|
+
if isinstance(iterable, (Iterator, Generator, map)):
|
|
197
|
+
iterable,copy = itertools.tee(iterable, 2)
|
|
198
|
+
len_ = sum(1 for _ in copy)
|
|
199
|
+
else:
|
|
200
|
+
len_ = len(iterable)
|
|
201
|
+
self.total_bits += len_*self.bit_length
|
|
202
|
+
for i,j in zip(range(len_),iterable):
|
|
203
|
+
self[-i-1] = j
|