Skip to content

Commit

Permalink
2023 day 20 at last!
Browse files Browse the repository at this point in the history
  • Loading branch information
jwhitham committed Dec 23, 2023
1 parent aaa7028 commit 86f0a1c
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 1 deletion.
62 changes: 62 additions & 0 deletions 2023/20/analyse3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

import typing

"""
There are 48 flip flops. They are organised into 4 groups of 12.
The groups act as chaotic state machines, but I only really want to
know how often they generate a signal as the output.
The outputs go via nodes labelled "vf", "dh", "mk", "rn".
Day 8 again? Least common multiple?
"""

def main() -> None:
seen_before: typing.Dict[int, int] = {}
seen_first: typing.Dict[int, int] = {}
period: typing.Dict[int, int] = {}
for (i, line) in enumerate(open("part2.txt", "rt")):
for (j, value) in enumerate(line.split()[1]):
if value == "B":
print(f"counter {j} triggers at {i}", end="")
if j in seen_before:
p = i - seen_before[j]
print(f" period {p}")
if j in period:
assert period[j] == p
else:
period[j] = p
else:
print()
seen_before[j] = i
if j not in seen_first:
seen_first[j] = i

for j in range(4):
print(f"Counter {j} triggers at {seen_first[j]} + {period[j]} * x")

for j in range(4):
# Well, this is convenient...
assert seen_first[j] == period[j]

c1 = period[0]
for i in range(1, len(period)):
c2 = period[i]
c1 = lcm(c1, c2)

print("LCM", c1)

def lcm(a, b):
m = a * b
if not m: return 0
while True:
a %= b
if not a: return m // b
b %= a
if not b: return m // a



if __name__ == "__main__":
main()
34 changes: 33 additions & 1 deletion 2023/20/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,39 @@ def main() -> None:
assert Problem("input").part1() == 861743850
assert Problem("test2").part2(OUTPUT) == 1
print(Problem("input").part1())
print(Problem("input").part2())
try:
Problem("input").part2()
except TimeoutError:
pass

seen_first: typing.Dict[int, int] = {}
period: typing.Dict[int, int] = {}
for (i, line) in enumerate(open("part2.txt", "rt")):
for (j, value) in enumerate(line.split()[1]):
if value == "B":
if j not in seen_first:
seen_first[j] = i
elif j not in period:
period[j] = i - seen_first[j]

for j in range(4):
assert seen_first[j] == period[j]

c1 = period[0]
for i in range(1, len(period)):
c2 = period[i]
c1 = lcm(c1, c2)

print(c1)

def lcm(a, b):
m = a * b
if not m: return 0
while True:
a %= b
if not a: return m // b
b %= a
if not b: return m // a

if __name__ == "__main__":
main()

0 comments on commit 86f0a1c

Please sign in to comment.