Solve day 20 and day 21 part 1.
This commit is contained in:
parent
0d1b3fbc2c
commit
c5813e168b
108
d20.py
Normal file
108
d20.py
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
from lib import *
|
||||||
|
from math import lcm
|
||||||
|
|
||||||
|
EXAMPLE = """
|
||||||
|
broadcaster -> a, b, c
|
||||||
|
%a -> b
|
||||||
|
%b -> c
|
||||||
|
%c -> inv
|
||||||
|
&inv -> a
|
||||||
|
"""
|
||||||
|
|
||||||
|
EXAMPLE2 = """
|
||||||
|
broadcaster -> a
|
||||||
|
%a -> inv, con
|
||||||
|
&inv -> b
|
||||||
|
%b -> con
|
||||||
|
&con -> output
|
||||||
|
"""
|
||||||
|
|
||||||
|
def visualize(modules):
|
||||||
|
with open("g20.dot", 'w') as f:
|
||||||
|
f.write("digraph G {\n")
|
||||||
|
for m in modules.values():
|
||||||
|
for cm in m[3]:
|
||||||
|
f.write(" " + m[1] + ' -> ' + cm + "\n")
|
||||||
|
f.write("}")
|
||||||
|
|
||||||
|
def solve(i: Input, second=False):
|
||||||
|
res = 0
|
||||||
|
modules = {}
|
||||||
|
for line in i.lines():
|
||||||
|
if not line: continue
|
||||||
|
src, dsts = line.split(" -> ")
|
||||||
|
dsts = dsts.split(", ")
|
||||||
|
if src.startswith("%"): # flip-flop
|
||||||
|
modules[src[1:]] = [src[0], src[1:], 0, dsts]
|
||||||
|
elif src.startswith("&"): # conjunction
|
||||||
|
modules[src[1:]] = [src[0], src[1:], {}, dsts]
|
||||||
|
elif src.startswith("broadcaster"):
|
||||||
|
modules[src] = ["b", src, 0, dsts]
|
||||||
|
else:
|
||||||
|
raise Exception()
|
||||||
|
|
||||||
|
for m in modules.values():
|
||||||
|
for d in m[3]:
|
||||||
|
if d in modules and modules[d][0] == "&":
|
||||||
|
modules[d][2][m[1]] = 0
|
||||||
|
|
||||||
|
if second:
|
||||||
|
# visualize(modules)
|
||||||
|
periods = {d: [] for d in modules["kh"][2].keys()}
|
||||||
|
BUTTON_PUSHES = 10000
|
||||||
|
else:
|
||||||
|
BUTTON_PUSHES = 1000
|
||||||
|
|
||||||
|
lo, hi = 0, 0
|
||||||
|
for i in range(BUTTON_PUSHES):
|
||||||
|
qs = [("button module", "broadcaster", 0)]
|
||||||
|
while qs:
|
||||||
|
src, dst, sig = qs[0]
|
||||||
|
qs = qs[1:]
|
||||||
|
|
||||||
|
if sig == 0:
|
||||||
|
lo += 1
|
||||||
|
else:
|
||||||
|
hi += 1
|
||||||
|
|
||||||
|
if not dst in modules:
|
||||||
|
continue
|
||||||
|
|
||||||
|
m = modules[dst]
|
||||||
|
new_pulse = None
|
||||||
|
if m[0] == "b":
|
||||||
|
new_pulse = 0
|
||||||
|
elif m[0] == "%":
|
||||||
|
if sig == 0:
|
||||||
|
m[2] = (m[2] + 1) % 2
|
||||||
|
new_pulse = m[2]
|
||||||
|
elif m[0] == "&":
|
||||||
|
m[2][src] = sig
|
||||||
|
if all(s == 1 for s in m[2].values()):
|
||||||
|
new_pulse = 0
|
||||||
|
else:
|
||||||
|
new_pulse = 1
|
||||||
|
else:
|
||||||
|
raise Exception()
|
||||||
|
|
||||||
|
if new_pulse is not None:
|
||||||
|
for nxtdst in m[3]:
|
||||||
|
if second and nxtdst == "kh" and new_pulse == 1:
|
||||||
|
# print(f"{i:>4}: {dst[:4]:>4} -{new_pulse}> {nxtdst}")
|
||||||
|
periods[dst].append(i)
|
||||||
|
qs.append((dst, nxtdst, new_pulse))
|
||||||
|
if second:
|
||||||
|
# print(periods)
|
||||||
|
# Yeah, we got a bit lucky that this works, I guess, but it does.
|
||||||
|
return lcm(*[v[1] - v[0] for v in periods.values()])
|
||||||
|
return lo * hi
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DAY_INPUT = "i20.txt"
|
||||||
|
print("Example 1:", solve(Input(EXAMPLE)))
|
||||||
|
print("Example 2:", solve(Input(EXAMPLE2)))
|
||||||
|
print("Solution 1:", solve(Input(DAY_INPUT)))
|
||||||
|
print("Solution 2:", solve(Input(DAY_INPUT), True))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
55
d21.py
Normal file
55
d21.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
from lib import *
|
||||||
|
|
||||||
|
EXAMPLE = """
|
||||||
|
...........
|
||||||
|
.....###.#.
|
||||||
|
.###.##..#.
|
||||||
|
..#.#...#..
|
||||||
|
....#.#....
|
||||||
|
.##..S####.
|
||||||
|
.##..#...#.
|
||||||
|
.......##..
|
||||||
|
.##.#.####.
|
||||||
|
.##..##.##.
|
||||||
|
...........
|
||||||
|
"""
|
||||||
|
|
||||||
|
def solve(i: Input, second=False):
|
||||||
|
res = 0
|
||||||
|
g = i.grid2()
|
||||||
|
s = g.find('S')[0]
|
||||||
|
g[s] = 'O'
|
||||||
|
# steps = 64
|
||||||
|
steps = 26501365
|
||||||
|
seen = set()
|
||||||
|
for i in range(steps):
|
||||||
|
os = tuple(g.find('O'))
|
||||||
|
if os in seen:
|
||||||
|
seen.add(os)
|
||||||
|
print(f"SEEN {i}")
|
||||||
|
break
|
||||||
|
|
||||||
|
for o in os:
|
||||||
|
g[o] = '.'
|
||||||
|
|
||||||
|
for o in os:
|
||||||
|
for nb in g.neighbors_ort(o):
|
||||||
|
if not g[nb] == "#":
|
||||||
|
g[nb] = 'O'
|
||||||
|
return len(g.find('O'))
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DAY_INPUT = "i21.txt"
|
||||||
|
|
||||||
|
print("Example 1:", solve(Input(EXAMPLE)))
|
||||||
|
print("Solution 1:", solve(Input(DAY_INPUT)))
|
||||||
|
return
|
||||||
|
|
||||||
|
print("Example 2:", solve(Input(EXAMPLE), True))
|
||||||
|
return
|
||||||
|
|
||||||
|
print("Solution 2:", solve(Input(DAY_INPUT), True))
|
||||||
|
return
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Reference in New Issue
Block a user