Finish 2021 thanks so much Eric
This commit is contained in:
parent
b622ca92b9
commit
b747d3973a
121
2021/d19.py
Normal file
121
2021/d19.py
Normal file
@ -0,0 +1,121 @@
|
||||
from lib import get_data
|
||||
from lib import ints
|
||||
from collections import defaultdict
|
||||
from itertools import permutations, product
|
||||
|
||||
V3 = tuple[int, int, int]
|
||||
|
||||
data = get_data(__file__)
|
||||
scanners = []
|
||||
for block in data.split("\n\n"):
|
||||
scanner = []
|
||||
for line in block.splitlines()[1:]:
|
||||
a, b, c = ints(line)
|
||||
scanner.append((a, b, c))
|
||||
scanners.append(scanner)
|
||||
|
||||
|
||||
def rotate(vi: V3) -> list[V3]:
|
||||
r = []
|
||||
for p in permutations(vi):
|
||||
for f in product([1, -1], repeat=3):
|
||||
v = tuple([a * b for a, b in zip(p, f)])
|
||||
r.append(v)
|
||||
return r
|
||||
|
||||
|
||||
assert len(rotate((8, 0, 7))) == 48
|
||||
|
||||
|
||||
def sub(a: V3, b: V3) -> V3:
|
||||
return a[0] - b[0], a[1] - b[1], a[2] - b[2]
|
||||
|
||||
|
||||
def add(a: V3, b: V3) -> V3:
|
||||
return a[0] + b[0], a[1] + b[1], a[2] + b[2]
|
||||
|
||||
|
||||
def relative(scanner: list[V3]):
|
||||
d = defaultdict(list)
|
||||
for i in range(len(scanner)):
|
||||
for j in range(i + 1, len(scanner)):
|
||||
for ii, jj in [(i, j), (j, i)]:
|
||||
a, b = scanner[ii], scanner[jj]
|
||||
delta = sub(a, b)
|
||||
d[delta].append((a, b))
|
||||
return d
|
||||
|
||||
|
||||
def overlap(scanner_1, scanner_2):
|
||||
expected_overlaps = 15
|
||||
r1 = relative(scanner_1)
|
||||
scanners_2 = []
|
||||
for scanner in list(zip(*list(map(rotate, scanner_2)))):
|
||||
os = set()
|
||||
r2 = relative(scanner)
|
||||
# number of bacon pairs that have the same offset
|
||||
t = sum(1 for k1 in r1.keys() if k1 in r2)
|
||||
if t >= expected_overlaps:
|
||||
for k1, v1 in r1.items():
|
||||
if k1 in r2:
|
||||
((abs1, abs2),) = v1
|
||||
((rel1, rel2),) = r2[k1]
|
||||
os.add(sub(abs1, rel1))
|
||||
os.add(sub(abs2, rel2))
|
||||
if len(os) == 1:
|
||||
# found the right orientation for scanner_2
|
||||
scanners_2.append((os.pop(), scanner))
|
||||
else:
|
||||
r2 = None
|
||||
else:
|
||||
r2 = None
|
||||
|
||||
if len(scanners_2) == 0:
|
||||
return None
|
||||
((orig_2, scanner_2_rel),) = scanners_2
|
||||
scanner_2_abs = [add(orig_2, b) for b in scanner_2_rel]
|
||||
return orig_2, scanner_2_abs
|
||||
|
||||
|
||||
origs = [(0, 0, 0)]
|
||||
todo = set(range(len(scanners)))
|
||||
done = set([0]) if 0 in todo else set([todo.pop()])
|
||||
todo.discard(0)
|
||||
while todo:
|
||||
for i in range(len(scanners)):
|
||||
for j in range(len(scanners)):
|
||||
if i == j:
|
||||
continue
|
||||
if i not in done:
|
||||
continue
|
||||
if j in done:
|
||||
continue
|
||||
r = overlap(scanners[i], scanners[j])
|
||||
|
||||
if r is None:
|
||||
continue
|
||||
o, s2 = r
|
||||
origs.append(o)
|
||||
no = len(set(scanners[i]).intersection(s2))
|
||||
if no >= 12:
|
||||
scanners[j] = s2
|
||||
done.add(j)
|
||||
todo.discard(j)
|
||||
# print(f"{i} < {no} > {j} at {o}")
|
||||
|
||||
|
||||
all = []
|
||||
for s in scanners:
|
||||
all += s
|
||||
print(len(set(all)))
|
||||
|
||||
|
||||
def mdist(a, b):
|
||||
return sum(abs(aa - bb) for aa, bb in zip(a, b))
|
||||
|
||||
|
||||
m = 0
|
||||
for i in range(len(origs)):
|
||||
for j in range(i + 1, len(origs)):
|
||||
m = max(m, mdist(origs[i], origs[j]))
|
||||
print(m)
|
@ -190,7 +190,7 @@ Solutions and utility script for Advent of Code challenges in Python.
|
||||
- Day 16: 50:01 (Way too slow. Was non-trivial but fun. Much better was feasible.)
|
||||
- Day 17: 21:59 (Not tricky again but struggling for no reason.)
|
||||
- Day 18: 162:00 (I couldn't figure out how to solve it as a tree so I did the basic way.)
|
||||
- Day 19:
|
||||
- Day 19: days (Super hard for me but super fun ultimately once I had the right approach.)
|
||||
- Day 20: 105:00 (That wasn't easy but was able to solve in one go.)
|
||||
- Day 21: 37:45 (Wasn't hard but I was just too slow.)
|
||||
- Day 22: 142:00 (Wonderful problem and hard for me but learned something new for sure.)
|
||||
|
Loading…
Reference in New Issue
Block a user