2025-01-12 обсуждение кода
This commit is contained in:
+21
-21
@@ -1,7 +1,8 @@
|
|||||||
import cProfile
|
import cProfile
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
from collections.abc import Iterator
|
||||||
|
|
||||||
Node = tuple[int, int, int]
|
Node = tuple[int, int, int] # только аннотация
|
||||||
|
|
||||||
|
|
||||||
def get_data(input_file):
|
def get_data(input_file):
|
||||||
@@ -13,31 +14,30 @@ def get_data(input_file):
|
|||||||
def cidr4_to_node(cidr4: str) -> Node:
|
def cidr4_to_node(cidr4: str) -> Node:
|
||||||
ip, mask_len = cidr4.strip().split("/")
|
ip, mask_len = cidr4.strip().split("/")
|
||||||
mask_len = int(mask_len)
|
mask_len = int(mask_len)
|
||||||
added_ips_number = 0
|
|
||||||
a, b, c, d = list(map(int, ip.split(".")))
|
a, b, c, d = list(map(int, ip.split(".")))
|
||||||
ip_value = a * 256**3 + b * 256**2 + c * 256**1 + d * 256**0
|
ip_value = a * 256**3 + b * 256**2 + c * 256**1 + d * 256**0
|
||||||
|
added_ips_number = 0
|
||||||
return ip_value, mask_len, added_ips_number
|
return ip_value, mask_len, added_ips_number
|
||||||
|
|
||||||
|
|
||||||
def sort_nodes(nodes: list[Node]) -> list[Node]:
|
def sort_nodes(nodes: Iterator[Node]) -> list[Node]:
|
||||||
return sorted(nodes, key=lambda x: (x[1], x[0]))
|
return sorted(nodes, key=lambda x: (x[1], x[0]))
|
||||||
|
|
||||||
|
|
||||||
def data_to_nodes(data: list[str]) -> list[Node]:
|
def data_to_nodes(data: Iterator[str]) -> Iterator[Node]:
|
||||||
return list(map(cidr4_to_node, data))
|
return map(cidr4_to_node, data)
|
||||||
|
|
||||||
|
def get_mask(ip, mask_len) -> int:
|
||||||
def get_mask(node: Node) -> int:
|
mask = ((1<<mask_len) - 1) << (32 - mask_len)
|
||||||
value, mask_len, _ = node
|
netaddr = ip & mask
|
||||||
x = (2**mask_len - 1) << (32 - mask_len)
|
return netaddr
|
||||||
mask = value & x
|
|
||||||
return mask
|
|
||||||
|
|
||||||
|
|
||||||
def get_parent_mask(node: Node) -> Optional[int]:
|
def get_parent_mask(node: Node) -> Optional[int]:
|
||||||
|
a, b, _ = node
|
||||||
if node[1] == 0:
|
if node[1] == 0:
|
||||||
return None
|
return None
|
||||||
return get_mask((node[0], node[1] - 1, node[2]))
|
return get_mask(a, b-1)
|
||||||
|
|
||||||
|
|
||||||
def have_same_parent(a: Node, b: Node) -> bool:
|
def have_same_parent(a: Node, b: Node) -> bool:
|
||||||
@@ -51,6 +51,7 @@ def get_group_with_max_mask_len(nodes: list[Node]) -> list[Node]:
|
|||||||
|
|
||||||
def get_parent(a: Node, b: Node = None) -> Node:
|
def get_parent(a: Node, b: Node = None) -> Node:
|
||||||
ip_value = get_parent_mask(a)
|
ip_value = get_parent_mask(a)
|
||||||
|
# обычно стоит вскрыть кортеж
|
||||||
mask_len = a[1] - 1
|
mask_len = a[1] - 1
|
||||||
added_ips_number = a[2] + 2 ** (32 - a[1])
|
added_ips_number = a[2] + 2 ** (32 - a[1])
|
||||||
if b:
|
if b:
|
||||||
@@ -102,8 +103,7 @@ def merge_nodes(nodes: list[Node], required_len: int) -> list[Node]:
|
|||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
|
|
||||||
def node_to_cidr4(node: Node) -> str:
|
def node_to_cidr4(ip_value, mask_len) -> str:
|
||||||
ip_value, mask_len, _ = node
|
|
||||||
lst = [str(ip_value >> (i << 3) & 0xFF) for i in reversed(range(4))]
|
lst = [str(ip_value >> (i << 3) & 0xFF) for i in reversed(range(4))]
|
||||||
ip = ".".join(lst)
|
ip = ".".join(lst)
|
||||||
return f"{ip}/{mask_len}"
|
return f"{ip}/{mask_len}"
|
||||||
@@ -115,9 +115,9 @@ def answer(nodes: list[Node], required_len: int) -> tuple[list[str], int]:
|
|||||||
|
|
||||||
cidr4s = []
|
cidr4s = []
|
||||||
sum_added_ips = 0
|
sum_added_ips = 0
|
||||||
for node in merged_nodes:
|
for ip_value, mask_len, added_ips in merged_nodes:
|
||||||
cidr4s.append(node_to_cidr4(node))
|
cidr4s.append(node_to_cidr4(ip_value, mask_len))
|
||||||
sum_added_ips += node[2]
|
sum_added_ips += added_ips
|
||||||
return cidr4s, sum_added_ips
|
return cidr4s, sum_added_ips
|
||||||
|
|
||||||
|
|
||||||
@@ -161,10 +161,10 @@ if __name__ == "__main__":
|
|||||||
assert len(bin_c) == 32
|
assert len(bin_c) == 32
|
||||||
value_d = int(bin_d, 2)
|
value_d = int(bin_d, 2)
|
||||||
|
|
||||||
assert get_mask((value_a, 5, 0)) == value_c
|
assert get_mask(value_a, 5) == value_c
|
||||||
assert get_mask((value_b, 5, 0)) == value_c
|
assert get_mask(value_b, 5) == value_c
|
||||||
assert get_mask((0, 1, 0)) == 0
|
assert get_mask(0, 1) == 0
|
||||||
assert get_mask((0, 0, 0)) == 0
|
assert get_mask(0, 0) == 0
|
||||||
|
|
||||||
assert get_parent_mask((value_a, 6, 0)) == value_c
|
assert get_parent_mask((value_a, 6, 0)) == value_c
|
||||||
assert get_parent_mask((value_b, 6, 0)) == value_c
|
assert get_parent_mask((value_b, 6, 0)) == value_c
|
||||||
|
|||||||
Reference in New Issue
Block a user