75 lines
2.4 KiB
Python
75 lines
2.4 KiB
Python
|
import re
|
||
|
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"Reached 'ZZZ' in {iterations} iterations")
|
||
|
|
||
|
|
||
|
def part2(directions, nodes):
|
||
|
current_nodes = [k for k in nodes.keys() if k.endswith("A")]
|
||
|
iterations = [0] * len(current_nodes)
|
||
|
print(current_nodes, iterations)
|
||
|
|
||
|
for d in cycle(directions):
|
||
|
if all(c.endswith("Z") for c in current_nodes):
|
||
|
break
|
||
|
#iterations += len(current_nodes)
|
||
|
if d == "L":
|
||
|
new_nodes = []
|
||
|
for i, n in enumerate(current_nodes):
|
||
|
if not n.endswith("Z"):
|
||
|
new_nodes.append(nodes[n][0])
|
||
|
iterations[i] += 1
|
||
|
else:
|
||
|
new_nodes.append(n)
|
||
|
current_nodes = new_nodes
|
||
|
#current_nodes = [c if c.endswith("Z") else nodes[c][0] for c in current_nodes]
|
||
|
else:
|
||
|
new_nodes = []
|
||
|
for i, n in enumerate(current_nodes):
|
||
|
if not n.endswith("Z"):
|
||
|
new_nodes.append(nodes[n][1])
|
||
|
iterations[i] += 1
|
||
|
else:
|
||
|
new_nodes.append(n)
|
||
|
current_nodes = new_nodes
|
||
|
#current_nodes = [c if c.endswith("Z") else nodes[c][1] for c in current_nodes]
|
||
|
print(current_nodes, iterations)
|
||
|
|
||
|
|
||
|
print(f"Reached all nodes such that 'xxZ' in {iterations} 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)
|