bool-hybrid-array 9.11.9__py3-none-any.whl → 9.11.10__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 +1 -1
- bool_hybrid_array/__main__.py +1 -3
- bool_hybrid_array/_cppiostream.py +216 -0
- bool_hybrid_array/compile_core.pyd +0 -0
- bool_hybrid_array/core.c +9225 -17137
- bool_hybrid_array/core.py +7 -219
- bool_hybrid_array/int_array/__init__.py +2 -153
- bool_hybrid_array/int_array/core.py +154 -0
- {bool_hybrid_array-9.11.9.dist-info → bool_hybrid_array-9.11.10.dist-info}/METADATA +3 -2
- bool_hybrid_array-9.11.10.dist-info/RECORD +14 -0
- {bool_hybrid_array-9.11.9.dist-info → bool_hybrid_array-9.11.10.dist-info}/WHEEL +1 -1
- bool_hybrid_array/core.cp314-win_amd64.pyd +0 -0
- bool_hybrid_array-9.11.9.dist-info/RECORD +0 -13
- {bool_hybrid_array-9.11.9.dist-info → bool_hybrid_array-9.11.10.dist-info}/licenses/LICENSE +0 -0
- {bool_hybrid_array-9.11.9.dist-info → bool_hybrid_array-9.11.10.dist-info}/top_level.txt +0 -0
bool_hybrid_array/core.py
CHANGED
|
@@ -7,18 +7,13 @@ except:
|
|
|
7
7
|
import builtins
|
|
8
8
|
from types import MappingProxyType
|
|
9
9
|
import array,bisect,numpy as np
|
|
10
|
-
from collections.abc import MutableSequence,Iterable,Generator,Iterator,Sequence
|
|
10
|
+
from collections.abc import MutableSequence,Iterable,Generator,Iterator,Sequence,Collection
|
|
11
11
|
import itertools,copy,sys,math,weakref,random,mmap,os
|
|
12
12
|
from functools import reduce
|
|
13
13
|
import operator,ctypes,gc,abc,types
|
|
14
14
|
from functools import lru_cache
|
|
15
15
|
from typing import _GenericAlias
|
|
16
16
|
from typing import Callable, Union, Sequence, MutableSequence, Any, overload, Sized
|
|
17
|
-
from ctypes import *
|
|
18
|
-
try:
|
|
19
|
-
import msvcrt
|
|
20
|
-
except ImportError:
|
|
21
|
-
pass
|
|
22
17
|
hybrid_array_cache:list[tuple[Any]] = []
|
|
23
18
|
try:
|
|
24
19
|
msvcrt = ctypes.CDLL('msvcrt.dll')
|
|
@@ -334,7 +329,7 @@ class BoolHybridArray(MutableSequence,Exception,metaclass=ResurrectMeta):# type:
|
|
|
334
329
|
return f"BoolHybridArr([{','.join(map(str,self))}])"
|
|
335
330
|
def __reversed__(self):
|
|
336
331
|
if not self:return BHA_Iterator([])
|
|
337
|
-
return BHA_Iterator(map(self.__getitem__,range(-1,-1,-1)))
|
|
332
|
+
return BHA_Iterator(map(self.__getitem__,range(self.size-1,-1,-1)))
|
|
338
333
|
def insert(self, key: int, value: Any) -> None:
|
|
339
334
|
value = bool(value)
|
|
340
335
|
key = key if key >= 0 else key + self.size
|
|
@@ -872,7 +867,7 @@ def Ask_BHA(path):
|
|
|
872
867
|
if len(temp) == 1:
|
|
873
868
|
return temp[0]
|
|
874
869
|
return temp
|
|
875
|
-
class BHA_Queue:
|
|
870
|
+
class BHA_Queue(Collection,metaclass = ResurrectMeta):
|
|
876
871
|
def __init__(self,data = (),*a,**k):
|
|
877
872
|
self.a = BoolHybridArr(data,*a,**k)
|
|
878
873
|
self.b = BoolHybridArr([],*a,**k)
|
|
@@ -885,8 +880,9 @@ class BHA_Queue:
|
|
|
885
880
|
if self.b:
|
|
886
881
|
return self.b.pop()
|
|
887
882
|
elif self.a:
|
|
888
|
-
|
|
889
|
-
self.b
|
|
883
|
+
Type = self.b.Type
|
|
884
|
+
self.b = BoolHybridArr(reversed(self.a))
|
|
885
|
+
self.b.Type = Type
|
|
890
886
|
self.a.clear()
|
|
891
887
|
return self.dequeue()
|
|
892
888
|
else:
|
|
@@ -938,215 +934,7 @@ def numba_opt():
|
|
|
938
934
|
])
|
|
939
935
|
bisect.bisect_left = numba.njit(sig, cache=True)(bisect.bisect_left)
|
|
940
936
|
bisect.bisect_right = numba.njit(sig, cache=True)(bisect.bisect_right)
|
|
941
|
-
|
|
942
|
-
def __init__(self):
|
|
943
|
-
self._stdout = sys.stdout
|
|
944
|
-
if sys.platform == "win32":
|
|
945
|
-
self._get_char = lambda: ord(msvcrt.getche())
|
|
946
|
-
self.backch = " \b"
|
|
947
|
-
else:
|
|
948
|
-
libc_path = "libc.so.6" if sys.platform == "linux" else "libSystem.B.dylib"
|
|
949
|
-
self.libc = ctypes.cdll.LoadLibrary(libc_path)
|
|
950
|
-
self._get_char = lambda:(c:=ord(self.libc.getchar()),
|
|
951
|
-
self._stdout.write(chr(c)),self._stdout.flush())[0]
|
|
952
|
-
self.backch = "\b \b"
|
|
953
|
-
self._whitespace = {ord('\n'), ord('\t'), ord(' '), 0, ord("\r")}
|
|
954
|
-
self.getchar = self._get_char
|
|
955
|
-
self._buf = []
|
|
956
|
-
|
|
957
|
-
def _read_char(self):
|
|
958
|
-
while True:
|
|
959
|
-
if self._buf:char = self._buf.pop(0)
|
|
960
|
-
else:char = self._get_char()
|
|
961
|
-
if char in self._whitespace or char == -1:
|
|
962
|
-
continue
|
|
963
|
-
return char
|
|
964
|
-
|
|
965
|
-
def _parse_int(self):
|
|
966
|
-
chars = []
|
|
967
|
-
while True:
|
|
968
|
-
if self._buf:
|
|
969
|
-
char = self._buf.pop(0)
|
|
970
|
-
else:
|
|
971
|
-
char = self._get_char()
|
|
972
|
-
if char in self._whitespace or char == -1:
|
|
973
|
-
break
|
|
974
|
-
if char == 8:
|
|
975
|
-
sys.stdout.write(self.backch)
|
|
976
|
-
sys.stdout.flush()
|
|
977
|
-
try:
|
|
978
|
-
chars.pop()
|
|
979
|
-
except:
|
|
980
|
-
pass
|
|
981
|
-
continue
|
|
982
|
-
elif chr(char) not in '+-0123456789':
|
|
983
|
-
self._buf.append(char)
|
|
984
|
-
break
|
|
985
|
-
else:
|
|
986
|
-
chars.append(chr(char))
|
|
987
|
-
return ''.join(chars) if chars else '0'
|
|
988
|
-
|
|
989
|
-
def _parse_float(self):
|
|
990
|
-
chars = []
|
|
991
|
-
while True:
|
|
992
|
-
if self._buf:
|
|
993
|
-
char = self._buf.pop(0)
|
|
994
|
-
else:
|
|
995
|
-
char = self._get_char()
|
|
996
|
-
if char in self._whitespace or char == -1:
|
|
997
|
-
break
|
|
998
|
-
if char == 8:
|
|
999
|
-
sys.stdout.write(self.backch)
|
|
1000
|
-
sys.stdout.flush()
|
|
1001
|
-
try:
|
|
1002
|
-
chars.pop()
|
|
1003
|
-
except:
|
|
1004
|
-
pass
|
|
1005
|
-
continue
|
|
1006
|
-
elif chr(char) not in '+-0123456789.eE':
|
|
1007
|
-
self._buf.append(char)
|
|
1008
|
-
break
|
|
1009
|
-
chars.append(chr(char))
|
|
1010
|
-
return ''.join(chars) if chars else '0.0'
|
|
1011
|
-
|
|
1012
|
-
def _parse_complex(self):
|
|
1013
|
-
chars = []
|
|
1014
|
-
while True:
|
|
1015
|
-
if self._buf:
|
|
1016
|
-
char = self._buf.pop(0)
|
|
1017
|
-
else:
|
|
1018
|
-
char = self._get_char()
|
|
1019
|
-
if char in self._whitespace or char == -1:
|
|
1020
|
-
break
|
|
1021
|
-
if char == 8:
|
|
1022
|
-
sys.stdout.write(self.backch)
|
|
1023
|
-
sys.stdout.flush()
|
|
1024
|
-
try:
|
|
1025
|
-
chars.pop()
|
|
1026
|
-
except:
|
|
1027
|
-
pass
|
|
1028
|
-
continue
|
|
1029
|
-
if chr(char) not in '+-0123456789.eEj':
|
|
1030
|
-
self._buf.append(char)
|
|
1031
|
-
break
|
|
1032
|
-
chars.append(chr(char))
|
|
1033
|
-
return ''.join(chars) if chars else '0+0j'
|
|
1034
|
-
|
|
1035
|
-
def _parse_char(self):
|
|
1036
|
-
char = self._read_char()
|
|
1037
|
-
return chr(char) if char not in self._whitespace and char != -1 else '\0'
|
|
1038
|
-
|
|
1039
|
-
def _parse_char_array(self, max_len=1024):
|
|
1040
|
-
chars = []
|
|
1041
|
-
count = 0
|
|
1042
|
-
while count < max_len - 1:
|
|
1043
|
-
char = self._get_char()
|
|
1044
|
-
if char == 8:
|
|
1045
|
-
sys.stdout.write(self.backch)
|
|
1046
|
-
sys.stdout.flush()
|
|
1047
|
-
try:
|
|
1048
|
-
chars.pop()
|
|
1049
|
-
except:
|
|
1050
|
-
pass
|
|
1051
|
-
continue
|
|
1052
|
-
if char in self._whitespace or char == -1:
|
|
1053
|
-
break
|
|
1054
|
-
chars.append(chr(char))
|
|
1055
|
-
count += 1
|
|
1056
|
-
return ''.join(chars)
|
|
1057
|
-
def _parse_ptr(self):
|
|
1058
|
-
chars = []
|
|
1059
|
-
while True:
|
|
1060
|
-
if self._buf:
|
|
1061
|
-
char = self._buf.pop(0)
|
|
1062
|
-
else:
|
|
1063
|
-
char = self._get_char()
|
|
1064
|
-
if char in self._whitespace or char == -1:
|
|
1065
|
-
break
|
|
1066
|
-
if char == 8:
|
|
1067
|
-
sys.stdout.write(self.backch)
|
|
1068
|
-
sys.stdout.flush()
|
|
1069
|
-
try:
|
|
1070
|
-
chars.pop()
|
|
1071
|
-
except:
|
|
1072
|
-
pass
|
|
1073
|
-
continue
|
|
1074
|
-
if chr(char) not in '0123456789abcdefABCDEFx':
|
|
1075
|
-
self._buf.append(char)
|
|
1076
|
-
break
|
|
1077
|
-
chars.append(chr(char))
|
|
1078
|
-
return ''.join(chars) if chars else '0'
|
|
1079
|
-
def __rshift__(self, target):
|
|
1080
|
-
if isinstance(target, ctypes._SimpleCData):
|
|
1081
|
-
target_type = type(target)
|
|
1082
|
-
if target_type == c_void_p:
|
|
1083
|
-
ptr_str = self._parse_ptr()
|
|
1084
|
-
if ptr_str.startswith('0x') or ptr_str.startswith('0X'):
|
|
1085
|
-
val = c_void_p(int(ptr_str, 16))
|
|
1086
|
-
else:
|
|
1087
|
-
val = c_void_p(int(ptr_str) if ptr_str.isdigit() else 0)
|
|
1088
|
-
elif target_type == c_char_p:
|
|
1089
|
-
str_val = self._parse_char_array()
|
|
1090
|
-
val = c_char_p(str_val.encode('utf-8'))
|
|
1091
|
-
ctypes.memmove(target, val, len(str_val.encode('utf-8')))
|
|
1092
|
-
elif target_type == c_wchar_p:
|
|
1093
|
-
str_val = self._parse_char_array()
|
|
1094
|
-
val = c_wchar_p(str_val)
|
|
1095
|
-
ctypes.memmove(target, val, len(str_val) * ctypes.sizeof(c_wchar))
|
|
1096
|
-
elif np.issubdtype(np.dtype(target_type), np.integer):
|
|
1097
|
-
val = target_type(int(self._parse_int()))
|
|
1098
|
-
elif np.issubdtype(np.dtype(target_type), np.floating):
|
|
1099
|
-
val = target_type(float(self._parse_float()))
|
|
1100
|
-
elif np.issubdtype(np.dtype(target_type), np.complexfloating):
|
|
1101
|
-
val = target_type(complex(self._parse_complex()))
|
|
1102
|
-
elif target_type == c_char:
|
|
1103
|
-
val = c_char(self._parse_char().encode('utf-8')[0])
|
|
1104
|
-
elif target_type == c_wchar:
|
|
1105
|
-
val = c_wchar(self._parse_char())
|
|
1106
|
-
else:
|
|
1107
|
-
raise TypeError(f"Unsupported ctypes type: {target_type}")
|
|
1108
|
-
if target_type not in (c_char_p, c_wchar_p):
|
|
1109
|
-
ctypes.memmove(byref(target), byref(val), sizeof(target))
|
|
1110
|
-
elif isinstance(target, (np.generic, np.ndarray)):
|
|
1111
|
-
if isinstance(target, np.generic) or target.ndim == 0:
|
|
1112
|
-
if np.issubdtype(target.dtype, np.integer):
|
|
1113
|
-
val = np.array(self._parse_int(), dtype=target.dtype)
|
|
1114
|
-
elif np.issubdtype(target.dtype, np.floating):
|
|
1115
|
-
val = np.array(self._parse_float(), dtype=target.dtype)
|
|
1116
|
-
elif np.issubdtype(target.dtype, np.complexfloating):
|
|
1117
|
-
val = np.array(self._parse_complex(), dtype=target.dtype)
|
|
1118
|
-
elif np.issubdtype(target.dtype, np.character):
|
|
1119
|
-
val = np.array(self._parse_char(), dtype=target.dtype)
|
|
1120
|
-
else:
|
|
1121
|
-
val = np.array(self._parse_int(), dtype=target.dtype)
|
|
1122
|
-
target[...] = val[()]
|
|
1123
|
-
else:
|
|
1124
|
-
for i in range(target.size):
|
|
1125
|
-
if np.issubdtype(target.dtype, np.integer):
|
|
1126
|
-
val = np.array(self._parse_int(), dtype=target.dtype)
|
|
1127
|
-
elif np.issubdtype(target.dtype, np.floating):
|
|
1128
|
-
val = np.array(self._parse_float(), dtype=target.dtype)
|
|
1129
|
-
elif np.issubdtype(target.dtype, np.complexfloating):
|
|
1130
|
-
val = np.array(self._parse_complex(), dtype=target.dtype)
|
|
1131
|
-
elif np.issubdtype(target.dtype, np.character):
|
|
1132
|
-
val = np.array(self._parse_char(), dtype=target.dtype)
|
|
1133
|
-
else:
|
|
1134
|
-
val = np.array(self._parse_int(), dtype=target.dtype)
|
|
1135
|
-
target.flat[i] = val[()]
|
|
1136
|
-
else:
|
|
1137
|
-
raise TypeError(f"Unsupported target type: {type(target)}")
|
|
1138
|
-
return self
|
|
1139
|
-
__str__ = lambda self:""
|
|
1140
|
-
__repr__ = lambda self:""
|
|
1141
|
-
class OutPutObject:
|
|
1142
|
-
def __lshift__(self, data):
|
|
1143
|
-
sys.stdout.write(str(data))
|
|
1144
|
-
return self
|
|
1145
|
-
__str__ = lambda self:""
|
|
1146
|
-
__repr__ = lambda self:""
|
|
1147
|
-
cin = InPutObject()
|
|
1148
|
-
cout = OutPutObject()
|
|
1149
|
-
endl = "\n"
|
|
937
|
+
from ._cppiostream import cin,cout,endl
|
|
1150
938
|
builtins.np = np
|
|
1151
939
|
builtins.T = BHA_bool(1)
|
|
1152
940
|
builtins.F = BHA_bool(0)
|
|
@@ -1,155 +1,4 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
from
|
|
3
|
-
from
|
|
4
|
-
import builtins
|
|
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
|
-
__del__ = lambda self:self
|
|
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(self.__class__, self).__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(self.__class__, self).__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
|
-
tmp = list(self)
|
|
99
|
-
tmp[key] = value
|
|
100
|
-
self.__init__(tmp)
|
|
101
|
-
def __iter__(self):
|
|
102
|
-
return map(self.__getitem__,range(len(self)))
|
|
103
|
-
|
|
104
|
-
def __str__(self):
|
|
105
|
-
return f"IntHybridArray([{', '.join(map(str, self))}])"
|
|
106
|
-
__repr__ = __str__
|
|
107
|
-
|
|
108
|
-
def __len__(self):
|
|
109
|
-
return self.total_bits // self.bit_length
|
|
110
|
-
def __delitem__(self, index: int = -1):
|
|
111
|
-
index = index if index >= 0 else index + len(self)
|
|
112
|
-
if not (0 <= index < len(self)):
|
|
113
|
-
raise IndexError("删除索引超出范围")
|
|
114
|
-
target_num = self[index]
|
|
115
|
-
pop_bit_start = index * self.bit_length
|
|
116
|
-
pop_bit_end = pop_bit_start + self.bit_length
|
|
117
|
-
for _ in range(self.bit_length):
|
|
118
|
-
super().__delitem__(pop_bit_start)
|
|
119
|
-
self.total_bits -= self.bit_length
|
|
120
|
-
def index(self, value):
|
|
121
|
-
value = int(value)
|
|
122
|
-
x = f"{value} 不在 IntHybridArray 中"
|
|
123
|
-
for idx in range(len(self)+1>>1):
|
|
124
|
-
if self[idx] == value:
|
|
125
|
-
return idx
|
|
126
|
-
elif self[-idx] == value:
|
|
127
|
-
x = len(self)-idx
|
|
128
|
-
if x != f"{value} 不在 IntHybridArray 中":
|
|
129
|
-
return x
|
|
130
|
-
raise ValueError(x)
|
|
131
|
-
def rindex(self, value):
|
|
132
|
-
value = int(value)
|
|
133
|
-
x = f"{value} 不在 IntHybridArray 中"
|
|
134
|
-
for idx in range(len(self)+1>>1):
|
|
135
|
-
if self[-idx] == value:
|
|
136
|
-
return -idx
|
|
137
|
-
elif self[idx] == value:
|
|
138
|
-
x = -(len(self)-idx)
|
|
139
|
-
if x != f"{value} 不在 IntHybridArray 中":
|
|
140
|
-
return x
|
|
141
|
-
raise ValueError(x)
|
|
142
|
-
def extend(self, iterable:Iterable) -> None:
|
|
143
|
-
if isinstance(iterable, (Iterator, Generator, map)):
|
|
144
|
-
iterable,copy = itertools.tee(iterable, 2)
|
|
145
|
-
len_ = sum(1 for _ in copy)
|
|
146
|
-
else:
|
|
147
|
-
len_ = len(iterable)
|
|
148
|
-
self.total_bits += len_*self.bit_length
|
|
149
|
-
for i,j in zip(range(len_),iterable):
|
|
150
|
-
self[-i-1] = j
|
|
151
|
-
def append(self,value):
|
|
152
|
-
self.total_bits += self.bit_length
|
|
153
|
-
self.size = self.total_bits
|
|
154
|
-
self[-1] = value
|
|
2
|
+
try:from .compile_core import *
|
|
3
|
+
except:from .core import *
|
|
155
4
|
__all__ = tuple(globals())
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from collections.abc import Iterable
|
|
3
|
+
from ..core import *
|
|
4
|
+
import builtins
|
|
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
|
+
__del__ = lambda self:self
|
|
10
|
+
class IntHybridArray(BoolHybridArray,metaclass=ResurrectMeta):
|
|
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(self.__class__, self).__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(self.__class__, self).__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
|
+
tmp = list(self)
|
|
99
|
+
tmp[key] = value
|
|
100
|
+
self.__init__(tmp)
|
|
101
|
+
def __iter__(self):
|
|
102
|
+
return map(self.__getitem__,range(len(self)))
|
|
103
|
+
|
|
104
|
+
def __str__(self):
|
|
105
|
+
return f"IntHybridArray([{', '.join(map(str, self))}])"
|
|
106
|
+
__repr__ = __str__
|
|
107
|
+
|
|
108
|
+
def __len__(self):
|
|
109
|
+
return self.total_bits // self.bit_length
|
|
110
|
+
def __delitem__(self, index: int = -1):
|
|
111
|
+
index = index if index >= 0 else index + len(self)
|
|
112
|
+
if not (0 <= index < len(self)):
|
|
113
|
+
raise IndexError("删除索引超出范围")
|
|
114
|
+
target_num = self[index]
|
|
115
|
+
pop_bit_start = index * self.bit_length
|
|
116
|
+
pop_bit_end = pop_bit_start + self.bit_length
|
|
117
|
+
for _ in range(self.bit_length):
|
|
118
|
+
super().__delitem__(pop_bit_start)
|
|
119
|
+
self.total_bits -= self.bit_length
|
|
120
|
+
def index(self, value):
|
|
121
|
+
value = int(value)
|
|
122
|
+
x = f"{value} 不在 IntHybridArray 中"
|
|
123
|
+
for idx in range(len(self)+1>>1):
|
|
124
|
+
if self[idx] == value:
|
|
125
|
+
return idx
|
|
126
|
+
elif self[-idx] == value:
|
|
127
|
+
x = len(self)-idx
|
|
128
|
+
if x != f"{value} 不在 IntHybridArray 中":
|
|
129
|
+
return x
|
|
130
|
+
raise ValueError(x)
|
|
131
|
+
def rindex(self, value):
|
|
132
|
+
value = int(value)
|
|
133
|
+
x = f"{value} 不在 IntHybridArray 中"
|
|
134
|
+
for idx in range(len(self)+1>>1):
|
|
135
|
+
if self[-idx] == value:
|
|
136
|
+
return -idx
|
|
137
|
+
elif self[idx] == value:
|
|
138
|
+
x = -(len(self)-idx)
|
|
139
|
+
if x != f"{value} 不在 IntHybridArray 中":
|
|
140
|
+
return x
|
|
141
|
+
raise ValueError(x)
|
|
142
|
+
def extend(self, iterable:Iterable) -> None:
|
|
143
|
+
if isinstance(iterable, (Iterator, Generator, map)):
|
|
144
|
+
iterable,copy = itertools.tee(iterable, 2)
|
|
145
|
+
len_ = sum(1 for _ in copy)
|
|
146
|
+
else:
|
|
147
|
+
len_ = len(iterable)
|
|
148
|
+
self.total_bits += len_*self.bit_length
|
|
149
|
+
for i,j in zip(range(len_),iterable):
|
|
150
|
+
self[-i-1] = j
|
|
151
|
+
def append(self,value):
|
|
152
|
+
self.total_bits += self.bit_length
|
|
153
|
+
self.size = self.total_bits
|
|
154
|
+
self[-1] = value
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bool-hybrid-array
|
|
3
|
-
Version: 9.11.
|
|
3
|
+
Version: 9.11.10
|
|
4
4
|
Summary: 一个高效的布尔数组(密集+稀疏混合存储,节省内存)
|
|
5
5
|
Home-page: https://github.com/BKsell/bool-hybrid-array
|
|
6
6
|
Author: 蔡靖杰
|
|
@@ -614,7 +614,8 @@ print(f"出队2个元素后: {q}") # 输出:BHA_Queue([T,T,F,T,F])
|
|
|
614
614
|
* **9.11.6**:修复从9.11.3版本开始cpython用户无法安装bool-hybrid-array包的问题
|
|
615
615
|
* **9.11.7**:修复TypeError: 'map' object is not reversible的错误
|
|
616
616
|
* **9.11.8**:增加了Windows系统Python3.14的C扩展优化
|
|
617
|
-
* **9.11.9**:修复BHA_Queue的bug,新增cin和cout(使用方式:a = ctypes.c_int();cin >> a;cout << a
|
|
617
|
+
* **9.11.9**:修复BHA_Queue的bug,新增cin和cout(使用方式:a = ctypes.c_int();cin >> a;cout << a,支持各种ctypes类型、numpy标量)
|
|
618
|
+
* **9.11.10**:修复cin的AttributeError的错误
|
|
618
619
|
|
|
619
620
|
|
|
620
621
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
bool_hybrid_array/__init__.py,sha256=KzXCj4pevLEmZMp789nBkklGWOVGVy7iUohoA3cxhL8,1078
|
|
2
|
+
bool_hybrid_array/__main__.py,sha256=uFyebfsZl1tW54AVcc6IDhk36BglTGb_Vw3Djx8pq00,8987
|
|
3
|
+
bool_hybrid_array/_cppiostream.py,sha256=uisSGktor52VFxhTcMN011RtzuUE8O1Fgz2VltnPi3c,8447
|
|
4
|
+
bool_hybrid_array/compile_core.pyd,sha256=_bSaBSVM8x_fkxdP_-4AiIYWVEkTgV3DWCPXzP-i-00,556544
|
|
5
|
+
bool_hybrid_array/core.c,sha256=6jlDe0FTZweoWtfhabEQMOk7kfwaiPFDoe0yYPCMpS8,3230449
|
|
6
|
+
bool_hybrid_array/core.py,sha256=nv-veRvbioLefXCe66Py1avxb7_8OZbT5CeyQm-ErQE,42031
|
|
7
|
+
bool_hybrid_array/秘密.md,sha256=Ii2NvXmv-Ktu04zJsGLcQZvlzT4gOatByE4B2wTK1Ks,48
|
|
8
|
+
bool_hybrid_array/int_array/__init__.py,sha256=CCKDUL5GBAXOprc9FhtLNL_rP4IDhvGVWJ-Dporp6YI,112
|
|
9
|
+
bool_hybrid_array/int_array/core.py,sha256=hnXHSLabtbDCnO3JX0M5tsF0BWlQpjWKu7RplMx7i8A,6236
|
|
10
|
+
bool_hybrid_array-9.11.10.dist-info/licenses/LICENSE,sha256=Sg4rnGXkBDYkwJCWyxdWp5H60rhVAxpNvFh_l3JWZdY,1070
|
|
11
|
+
bool_hybrid_array-9.11.10.dist-info/METADATA,sha256=kmw6K6GnXPoBGWxeNaZ8Rm4HGPdjWwqIsw3WgP2gkM8,26133
|
|
12
|
+
bool_hybrid_array-9.11.10.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
13
|
+
bool_hybrid_array-9.11.10.dist-info/top_level.txt,sha256=vk-TD77wuVQsN1rJ6uVWZX4sC_wya_WplRDwQKJoBZM,18
|
|
14
|
+
bool_hybrid_array-9.11.10.dist-info/RECORD,,
|
|
Binary file
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
bool_hybrid_array/__init__.py,sha256=QGalf9IbiqJSBW7wmbpduG333dmkQISsLMeQja-qtSg,1077
|
|
2
|
-
bool_hybrid_array/__main__.py,sha256=pjoWN4Noa_K44fqQPqp8H-diKSDf0Da8hdWFgvWUigQ,9083
|
|
3
|
-
bool_hybrid_array/compile_core.pyd,sha256=lriymUZtvs_ryeGM_K8gM33iCIfxRH5Zr5GPKhuNCtw,555520
|
|
4
|
-
bool_hybrid_array/core.c,sha256=VN0qsWCaJc0lEz6zHt7AFJsUcTieM5hkNtSeKh4ilIs,3616205
|
|
5
|
-
bool_hybrid_array/core.cp314-win_amd64.pyd,sha256=bAIpe0dUTBNMVbIDlZoBdtLsN7TmzaOo2KcY16BEvYU,633856
|
|
6
|
-
bool_hybrid_array/core.py,sha256=A1Lwn91T9N9-BhRBDIKJjVzvBVS036Mnaal3bfXN4To,50424
|
|
7
|
-
bool_hybrid_array/秘密.md,sha256=Ii2NvXmv-Ktu04zJsGLcQZvlzT4gOatByE4B2wTK1Ks,48
|
|
8
|
-
bool_hybrid_array/int_array/__init__.py,sha256=HPBdZu5qlXaRI4n_oK6WhnG4ml8H-FP1G44igVxPJIA,6225
|
|
9
|
-
bool_hybrid_array-9.11.9.dist-info/licenses/LICENSE,sha256=Sg4rnGXkBDYkwJCWyxdWp5H60rhVAxpNvFh_l3JWZdY,1070
|
|
10
|
-
bool_hybrid_array-9.11.9.dist-info/METADATA,sha256=8aIKi87Xbs3_J6hkpDGIjFXhE9GiVB2qH2-hJJJXJ7Y,26038
|
|
11
|
-
bool_hybrid_array-9.11.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
-
bool_hybrid_array-9.11.9.dist-info/top_level.txt,sha256=vk-TD77wuVQsN1rJ6uVWZX4sC_wya_WplRDwQKJoBZM,18
|
|
13
|
-
bool_hybrid_array-9.11.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|