-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathday12.py
71 lines (65 loc) · 1.77 KB
/
day12.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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from benchy import minibench
lines = open("day12.txt").read().split("\n")
cache = {}
def count(syms, sp, rules, rp):
# skip empty
while sp < len(syms) and syms[sp] == ".":
sp += 1
if (sp, rp) in cache:
return cache[(sp, rp)]
if rp == len(rules):
if all([c == "." or c == "?" for c in syms[sp:]]):
z = 1
else:
z = 0
cache[(sp, rp)] = z
return z
if sp >= len(syms):
return 0
l = rules[rp]
s = p = sp
# scan the current rule
f = False
while l > 0 and p < len(syms) and (syms[p] == "?" or syms[p] == "#"):
f = f or syms[p] == "#"
p += 1
l -= 1
# not able to fit
if l > 0 and (f or p >= len(syms)):
return 0
if l > 0 and p < len(syms):
return count(syms, p + 1, rules, rp)
cnt = 0
# Following symbol has to be '.' or '?' or EOL
if p == len(syms) or syms[p] != "#":
cnt += count(syms, p + 1, rules, rp + 1)
# turn '?' at the start into '.'
while p < len(syms) and syms[s] == "?" and (syms[p] == "#" or syms[p] == "?"):
f = f or syms[p] == "#"
s += 1
p += 1
if p == len(syms) or syms[p] != "#":
cnt += count(syms, p + 1, rules, rp + 1)
if not f and p < len(syms):
cnt += count(syms, p + 1, rules, rp)
cache[(sp, rp)] = cnt
return cnt
def run(mult):
tot = 0
for l in lines:
a, b = l.split()
c = list(map(int, b.split(",")))
cache.clear()
aa = a
if (mult > 1):
aa = ((a + "?") * 5)[:-1]
z = count(aa , 0, c * mult , 0)
tot += z
return tot
def part1():
return run(1)
def part2():
return run(5)
print(part1())
print(part2())
minibench({"part1": part1, "part2": part2})