day08
parent
1827398746
commit
568f6f1350
|
|
@ -0,0 +1,106 @@
|
|||
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]}")
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
import itertools
|
||||
import math
|
||||
|
||||
def single_circuit(circuits, num_junctions):
|
||||
for circuit in circuits:
|
||||
if len(circuit) == num_junctions:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
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, infinite=99999):
|
||||
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" # 25272
|
||||
filename = "day08/input" # 274150525
|
||||
|
||||
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 as then "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
|
||||
dist = 0
|
||||
print("Make connections")
|
||||
while True:
|
||||
a,b = get_lowest_distance(junctions_distance)
|
||||
|
||||
if add_circuit(a,b,circuits):
|
||||
connections += 1
|
||||
|
||||
if single_circuit(circuits, len(junctions)):
|
||||
dist = a[0] * b[0]
|
||||
break
|
||||
|
||||
if connections % 1000 == 0:
|
||||
print(f"Connections: {connections}")
|
||||
|
||||
print(f"Distance junction boxes: {dist}")
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
162,817,812
|
||||
57,618,57
|
||||
906,360,560
|
||||
592,479,940
|
||||
352,342,300
|
||||
466,668,158
|
||||
542,29,236
|
||||
431,825,988
|
||||
739,650,466
|
||||
52,470,668
|
||||
216,146,977
|
||||
819,987,18
|
||||
117,168,530
|
||||
805,96,715
|
||||
346,949,466
|
||||
970,615,88
|
||||
941,993,340
|
||||
862,61,35
|
||||
984,92,344
|
||||
425,690,689
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue