advent-of-code/2023/python/day08.py

69 lines
1.7 KiB
Python
Raw Normal View History

2023-12-08 14:58:49 +00:00
import shared
from scanf import scanf
2023-12-08 18:42:42 +00:00
from pprint import pprint
from math import lcm
2023-12-08 14:58:49 +00:00
2023-12-08 18:42:42 +00:00
def setup(rows):
2023-12-08 14:58:49 +00:00
MAP = {}
instructions = rows.pop(0)
rows.pop(0)
instructions = instructions.replace("L", "0")
instructions = instructions.replace("R", "1")
instructions = [int(x) for x in instructions]
for row in rows:
entry, left, right = scanf("%s = (%s, %s)", row)
2023-12-08 18:42:42 +00:00
MAP[entry] = [left, right]
return MAP, instructions
2023-12-08 14:58:49 +00:00
2023-12-08 18:42:42 +00:00
# @shared.profile
def part1(rows):
_map, _instructions = setup(rows)
count, _ = find("AAA", _instructions, _map)
2023-12-08 14:58:49 +00:00
print(count)
2023-12-08 18:42:42 +00:00
2023-12-08 14:58:49 +00:00
# @shared.profile
2023-12-08 18:42:42 +00:00
def part2(rows):
_map, _instructions = setup(rows)
starting_points = [k for k in _map.keys() if k[-1] == "A"]
ending_points = [k for k in _map.keys() if k[-1] == "Z"]
ends = []
for s in starting_points:
count, end = find(s, _instructions, _map, None)
ends.append(count)
print(lcm(*ends))
2023-12-08 14:58:49 +00:00
2023-12-08 18:42:42 +00:00
def find(start, instructions, MAP, target="ZZZ"):
2023-12-08 14:58:49 +00:00
count = 0
2023-12-08 18:42:42 +00:00
current = start
2023-12-08 14:58:49 +00:00
while True:
idx = count % len(instructions)
l_r = instructions[idx]
current = MAP[current][l_r]
count += 1
2023-12-08 18:42:42 +00:00
if target is None:
if current.endswith("Z"):
return count, current
elif current == target:
return count, current
2023-12-08 14:58:49 +00:00
def main():
rows = [row for row in shared.load_rows(8)]
with shared.elapsed_timer() as elapsed:
part1(rows[:])
print("🕒", elapsed())
rows = [row for row in shared.load_rows(8, True)]
with shared.elapsed_timer() as elapsed:
part2(rows[:])
print("🕒", elapsed())
if __name__ == "__main__":
main()