mirror of
https://github.com/thib8956/advent-of-code.git
synced 2025-08-24 08:21:57 +00:00
chore: create new project structure and aoc.py runner script
This commit is contained in:
75
adventofcode/2023/day8/day8.py
Normal file
75
adventofcode/2023/day8/day8.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import re
|
||||
import math
|
||||
from itertools import cycle
|
||||
|
||||
def parse_input(infile):
|
||||
with open(infile) as f:
|
||||
content = f.read().rstrip()
|
||||
directions, nodes = content.split("\n\n")
|
||||
directions = directions.strip()
|
||||
nodes = nodes.split("\n")
|
||||
nodes = [n.split(" = ") for n in nodes]
|
||||
nodes = {k: re.findall(r"\w{3}", v) for k, v in nodes}
|
||||
return directions, nodes
|
||||
|
||||
|
||||
def part1(directions, nodes):
|
||||
iterations = 0
|
||||
current_node = "AAA"
|
||||
for d in cycle(directions):
|
||||
if current_node == "ZZZ":
|
||||
break
|
||||
iterations += 1
|
||||
if d == "L":
|
||||
current_node = nodes[current_node][0]
|
||||
else:
|
||||
current_node = nodes[current_node][1]
|
||||
print(f"Part 1: reached 'ZZZ' in {iterations} iterations")
|
||||
|
||||
|
||||
def part2(directions, nodes):
|
||||
current_nodes = [k for k in nodes.keys() if k.endswith("A")]
|
||||
# keep track of iterations number for each visited node
|
||||
# (the number will stop to beeing incremented once the node n_i value reached the target value 'xxZ')
|
||||
iterations = [0] * len(current_nodes)
|
||||
|
||||
for d in cycle(directions):
|
||||
if all(c.endswith("Z") for c in current_nodes):
|
||||
break
|
||||
|
||||
if d == "L":
|
||||
new_nodes = []
|
||||
for i, n in enumerate(current_nodes):
|
||||
if n.endswith("Z"): # end condition already reached for this node
|
||||
new_nodes.append(n)
|
||||
else:
|
||||
new_nodes.append(nodes[n][0])
|
||||
iterations[i] += 1
|
||||
current_nodes = new_nodes
|
||||
else:
|
||||
new_nodes = []
|
||||
for i, n in enumerate(current_nodes):
|
||||
if n.endswith("Z"): # end condition already reached for this node
|
||||
new_nodes.append(n)
|
||||
else:
|
||||
new_nodes.append(nodes[n][1])
|
||||
iterations[i] += 1
|
||||
current_nodes = new_nodes
|
||||
|
||||
# the result is the lowest common multiple between the number of iterations
|
||||
# for each node
|
||||
result = math.lcm(*iterations)
|
||||
print(f"Part 2: reached all nodes such that 'xxZ' in {result} iterations")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
import os
|
||||
SCRIPTPATH = os.path.dirname(os.path.realpath(__file__))
|
||||
infile = sys.argv[1] if len(sys.argv) == 2 else "example.txt"
|
||||
|
||||
directions, nodes = parse_input(os.path.join(SCRIPTPATH, infile))
|
||||
part1(directions, nodes)
|
||||
|
||||
directions, nodes = parse_input(os.path.join(SCRIPTPATH, infile))
|
||||
part2(directions, nodes)
|
Reference in New Issue
Block a user