import itertools import math def get_circuit(a,circuits): if len(circuits) == 0: return None for circ in circuits: for pos in circ: if pos == a: return circ return None def add_circuit(a,b,circuits): circ_a = get_circuit(a,circuits) circ_b = get_circuit(b,circuits) if circ_a is None and circ_b is None: circuits.append([a,b]) return True if circ_a is None and not circ_b is None: circ_b.append(a) return True if not circ_a is None and circ_b is None: circ_a.append(b) return True if not circ_a is None and not circ_b is None: if circ_a == circ_b: # Already part of same circuit return True else: # Merge circuits... # Copy a to b for circ in circ_a: circ_b.append(circ) # Empty a for _ in range(0, len(circ_a)): circ_a.pop() return True def get_lowest_distance(junctions_distance): a,b,_ = junctions_distance.pop() return a,b def distance(a,b): # https://en.wikipedia.org/wiki/Euclidean_distance return math.sqrt( pow((a[0]-b[0]),2) + pow((a[1]-b[1]),2) + pow((a[2]-b[2]),2) ) def read_input(filename): space = [] for line in open(filename).read().splitlines(): x,y,z = line.split(",") space.append((int(x), int(y), int(z))) return space filename = "day08/example_input" # 40 max_connections = 10 filename = "day08/input" # 115885 max_connections = 1000 junctions = read_input(filename) # build list of (unique) combinations junctions_comb = itertools.combinations(junctions,2) print("Calculate distances") # Add distance to the list junctions_distance = [] for a,b in junctions_comb: dist = distance(a,b) junctions_distance.append((a,b,dist)) # Sort distance list, reversed so "pop()" will get/remove the shortest distance def jd_sort(junc_dist): return junc_dist[2] junctions_distance.sort(key=jd_sort, reverse=True) circuits = [] connections = 0 print("Make connections") while True: a,b = get_lowest_distance(junctions_distance) if add_circuit(a,b,circuits): connections += 1 if connections == max_connections: break if connections % 100 == 0: print(f"Connections: {connections}") sizes = [len(i) for i in circuits] sizes.sort(reverse=True) print(f"3 largest circuits multiplied: {sizes[0]*sizes[1]*sizes[2]}")