added smooth_merge_binaries function
This commit is contained in:
@@ -3,6 +3,7 @@ from ipaddress import IPv4Address
|
|||||||
from typing import List, Tuple
|
from typing import List, Tuple
|
||||||
from itertools import groupby
|
from itertools import groupby
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
import cProfile
|
||||||
|
|
||||||
|
|
||||||
def get_data(input_file):
|
def get_data(input_file):
|
||||||
@@ -70,6 +71,49 @@ def rough_merge_binaries(binaries: List[str], req_len: int) -> List[str]:
|
|||||||
return sorted(ips)
|
return sorted(ips)
|
||||||
|
|
||||||
|
|
||||||
|
def smooth_merge_binaries(binaries: List[str], req_len: int) -> List[str]:
|
||||||
|
non_reducible_ips = set()
|
||||||
|
ips = set()
|
||||||
|
for ip in binaries:
|
||||||
|
if "1" not in reduce_binary(ip):
|
||||||
|
non_reducible_ips.add(ip)
|
||||||
|
else:
|
||||||
|
ips.add(ip)
|
||||||
|
|
||||||
|
while len(ips) > 0 and len(ips) + len(non_reducible_ips) > req_len:
|
||||||
|
print(f"{req_len=} {len(ips) + len(non_reducible_ips)=}")
|
||||||
|
|
||||||
|
group_dict = defaultdict(list)
|
||||||
|
for ip in ips:
|
||||||
|
group_dict[ip.rfind("1")].append(ip)
|
||||||
|
|
||||||
|
max_len = max(group_dict)
|
||||||
|
lst = group_dict[max_len]
|
||||||
|
for x, y in zip(lst, lst[1:]):
|
||||||
|
i = x.rfind("1")
|
||||||
|
if y.startswith(x[:i]):
|
||||||
|
ips.remove(x)
|
||||||
|
ips.remove(y)
|
||||||
|
ips.add(reduce_binary(x))
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
x = lst[0]
|
||||||
|
ips.remove(x)
|
||||||
|
ips.add(reduce_binary(x))
|
||||||
|
|
||||||
|
_ips = ips | non_reducible_ips
|
||||||
|
non_reducible_ips = set()
|
||||||
|
ips = set()
|
||||||
|
for ip in _ips:
|
||||||
|
if "1" not in reduce_binary(ip):
|
||||||
|
non_reducible_ips.add(ip)
|
||||||
|
else:
|
||||||
|
ips.add(ip)
|
||||||
|
|
||||||
|
ips.update(non_reducible_ips)
|
||||||
|
return sorted(ips)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
file = "cidr4.txt"
|
file = "cidr4.txt"
|
||||||
required_len = 20
|
required_len = 20
|
||||||
@@ -82,6 +126,13 @@ def main():
|
|||||||
for ip in rough_merged_bin_ips:
|
for ip in rough_merged_bin_ips:
|
||||||
print(ip)
|
print(ip)
|
||||||
|
|
||||||
|
print("#" * 128)
|
||||||
|
|
||||||
|
smooth_merged_bin_ips = smooth_merge_binaries(rough_merged_bin_ips, required_len)
|
||||||
|
print(f"{len(smooth_merged_bin_ips)=}")
|
||||||
|
for ip in smooth_merged_bin_ips:
|
||||||
|
print(ip)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
assert cidr4_to_binary("4.78.139.0/24") == "00000100010011101000101100000000"
|
assert cidr4_to_binary("4.78.139.0/24") == "00000100010011101000101100000000"
|
||||||
@@ -103,3 +154,4 @@ if __name__ == "__main__":
|
|||||||
assert reduce_binary("00000000000010000000000000000000") == "0" * 32
|
assert reduce_binary("00000000000010000000000000000000") == "0" * 32
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
# cProfile.run("main()")
|
||||||
|
|||||||
Reference in New Issue
Block a user