generated from public/aoc_template
Compare commits
No commits in common. "bb4fde783fcd9ddba7a813c649ead76b3f27bde1" and "fdfa8a02b2079dfc90c9de5161c7ea237ea1404d" have entirely different histories.
bb4fde783f
...
fdfa8a02b2
50
day08.py
50
day08.py
@ -1,23 +1,9 @@
|
|||||||
import math
|
import math
|
||||||
|
from collections import defaultdict
|
||||||
from tools.aoc import AOCDay
|
from tools.aoc import AOCDay
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
def get_steps_to_z(inst: str, nodes: dict, from_node: str) -> int:
|
|
||||||
i_len = len(inst)
|
|
||||||
cur_step = 0
|
|
||||||
cur_node = from_node
|
|
||||||
while not cur_node.endswith("Z"):
|
|
||||||
if inst[cur_step % i_len] == "L":
|
|
||||||
cur_node = nodes[cur_node][0]
|
|
||||||
else:
|
|
||||||
cur_node = nodes[cur_node][1]
|
|
||||||
|
|
||||||
cur_step += 1
|
|
||||||
|
|
||||||
return cur_step
|
|
||||||
|
|
||||||
|
|
||||||
class Day(AOCDay):
|
class Day(AOCDay):
|
||||||
inputs = [
|
inputs = [
|
||||||
[
|
[
|
||||||
@ -35,21 +21,45 @@ class Day(AOCDay):
|
|||||||
inst = self.getInput()[0]
|
inst = self.getInput()[0]
|
||||||
nodes = {}
|
nodes = {}
|
||||||
for line in self.getInput()[2:]:
|
for line in self.getInput()[2:]:
|
||||||
node, paths = line.split(" = ")
|
node, pathhs = line.split(" = ")
|
||||||
pl, pr = paths.split(", ")
|
pl, pr = pathhs.split(", ")
|
||||||
nodes[node] = (pl[1:], pr[:-1])
|
nodes[node] = (pl[1:], pr[:-1])
|
||||||
|
|
||||||
return inst, nodes
|
return inst, nodes
|
||||||
|
|
||||||
def part1(self) -> Any:
|
def part1(self) -> Any:
|
||||||
inst, nodes = self.parse_input()
|
inst, nodes = self.parse_input()
|
||||||
return get_steps_to_z(inst, nodes, "AAA")
|
cur_node = "AAA"
|
||||||
|
cur_step = 0
|
||||||
|
while cur_node != "ZZZ":
|
||||||
|
dir = inst[cur_step % len(inst)]
|
||||||
|
if dir == "L":
|
||||||
|
cur_node = nodes[cur_node][0]
|
||||||
|
else:
|
||||||
|
cur_node = nodes[cur_node][1]
|
||||||
|
|
||||||
|
cur_step += 1
|
||||||
|
|
||||||
|
return cur_step
|
||||||
|
|
||||||
def part2(self) -> Any:
|
def part2(self) -> Any:
|
||||||
inst, nodes = self.parse_input()
|
inst, nodes = self.parse_input()
|
||||||
|
i_len = len(inst)
|
||||||
check_nodes = [x for x in nodes if x.endswith("A")]
|
check_nodes = [x for x in nodes if x.endswith("A")]
|
||||||
z_steps = [get_steps_to_z(inst, nodes, x) for x in check_nodes]
|
nodes_dp = defaultdict(dict)
|
||||||
return math.lcm(*z_steps)
|
for node in check_nodes:
|
||||||
|
cur_step = 0
|
||||||
|
cur_node = node
|
||||||
|
while (cur_node, cur_step % i_len) not in nodes_dp[node]:
|
||||||
|
nodes_dp[node][(cur_node, cur_step % i_len)] = cur_step
|
||||||
|
if inst[cur_step % i_len] == "L":
|
||||||
|
cur_node = nodes[cur_node][0]
|
||||||
|
else:
|
||||||
|
cur_node = nodes[cur_node][1]
|
||||||
|
|
||||||
|
cur_step += 1
|
||||||
|
|
||||||
|
return math.lcm(*[v for node in check_nodes for k, v in nodes_dp[node].items() if k[0].endswith("Z")])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user