-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path8.py
executable file
·57 lines (45 loc) · 1.41 KB
/
8.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/env python3
import lib
import sys, math, re, functools, operator, itertools, bisect
import numpy as np
from collections import defaultdict, deque, Counter
from itertools import accumulate, chain, pairwise, cycle
from functools import cache, reduce
# 21:00
infile = sys.argv[1] if len(sys.argv) > 1 else '8.in'
f = open(infile, 'r') if infile != '-' else sys.stdin
# data = f.read().strip()
# lines = list(map(str.strip, f))
lines = list(map(lib.Input, f))
# grid = list(list(ln) for ln in map(str.strip, f))
'''
LRRRLLRLLRRLRLRRRLRLRRRLRRLLRRRLRRLRLLRLLRRLRLLLLRRLRRLRLLRR
RTF = (TRM, KNP)
FNJ = (DRR, MJH)
KNM = (CGF, LSP)
'''
inst = lines[0].tr('LR', '01')
conn: dict[str, tuple[str, str]] = {}
for line in lines[2:]:
src, l, r = line.drop('=(,)').split()
conn[src] = (l, r)
def a_to_z() -> int:
curr = 'AAA'
for step, d in enumerate(cycle(map(int, inst)), 1):
curr = conn[curr][d]
if curr == 'ZZZ':
return step
def z_interval(src: str) -> int:
curr = src
dist_to = {}
for step, d in enumerate(cycle(map(int, inst)), 1):
curr = conn[curr][d]
if curr.endswith('Z'):
if curr in dist_to:
return step - dist_to[curr]
dist_to[curr] = step
print('part 1: ', a_to_z())
srcs = (curr for curr in conn if curr.endswith('A'))
loops = map(z_interval, srcs)
all_z = reduce(math.lcm, loops)
print('part 2: ', all_z)