Do day 19.
This commit is contained in:
139
d19.py
139
d19.py
@@ -1,29 +1,148 @@
|
||||
from lib import *
|
||||
|
||||
EXAMPLE = """
|
||||
EXAMPLE = """px{a<2006:qkq,m>2090:A,rfg}
|
||||
pv{a>1716:R,A}
|
||||
lnx{m>1548:A,A}
|
||||
rfg{s<537:gd,x>2440:R,A}
|
||||
qs{s>3448:A,lnx}
|
||||
qkq{x<1416:A,crn}
|
||||
crn{x>2662:A,R}
|
||||
in{s<1351:px,qqz}
|
||||
qqz{s>2770:qs,m<1801:hdj,R}
|
||||
gd{a>3333:R,R}
|
||||
hdj{m>838:A,pv}
|
||||
|
||||
{x=787,m=2655,a=1222,s=2876}
|
||||
{x=1679,m=44,a=2067,s=496}
|
||||
{x=2036,m=264,a=79,s=2244}
|
||||
{x=2461,m=1339,a=466,s=291}
|
||||
{x=2127,m=1623,a=2188,s=1013}
|
||||
"""
|
||||
|
||||
def solve(i: Input, second=False):
|
||||
res = 0
|
||||
i.stats()
|
||||
# g = i.grid2()
|
||||
# ls = i.lines()
|
||||
# ps = i.paras()
|
||||
ps = i.paras()
|
||||
wfs, parts = ps
|
||||
wfs = wfs.splitlines()
|
||||
parts = parts.splitlines()
|
||||
|
||||
workflows = {}
|
||||
for w in wfs:
|
||||
name, ins = w.split("{")
|
||||
ins = ins.replace("}", "")
|
||||
conds = ins.split(",")
|
||||
wf = []
|
||||
for cond in conds[:-1]:
|
||||
cmp, n = cond.split(":")
|
||||
if '<' in cmp:
|
||||
a, b = cmp.split('<')
|
||||
wf.append((a, 'smaller', int(b), n))
|
||||
elif '>' in cmp:
|
||||
a, b = cmp.split('>')
|
||||
wf.append((a, 'greater', int(b), n))
|
||||
else:
|
||||
raise Exception()
|
||||
wf.append(conds[-1:])
|
||||
workflows[name] = wf
|
||||
|
||||
def parse_part(part):
|
||||
d = {}
|
||||
p = part.replace("{", "").replace("}", "")
|
||||
for pair in p.split(","):
|
||||
a, b = pair.split("=")
|
||||
d[a] = int(b)
|
||||
return d
|
||||
|
||||
parts = list(map(parse_part, parts))
|
||||
if not second:
|
||||
for p in parts:
|
||||
current = 'in'
|
||||
while current not in ['A', 'R']:
|
||||
for inst in workflows[current]:
|
||||
if len(inst) == 4:
|
||||
letter = inst[0]
|
||||
value = inst[2]
|
||||
next = inst[3]
|
||||
if inst[1] == 'smaller':
|
||||
if p[letter] < value:
|
||||
current = next
|
||||
break
|
||||
elif inst[1] == 'greater':
|
||||
if p[letter] > value:
|
||||
current = next
|
||||
break
|
||||
else:
|
||||
raise Exception()
|
||||
elif len(inst) == 1:
|
||||
current = inst[0]
|
||||
else:
|
||||
raise Exception()
|
||||
if current == 'A':
|
||||
r = sum(p.values())
|
||||
res += r
|
||||
return res
|
||||
|
||||
ranges = [{c: (1, 4000) for c in 'xmas'}]
|
||||
ranges[0]['cur'] = 'in'
|
||||
ranges[0]['idx'] = 0
|
||||
accepted = []
|
||||
while ranges:
|
||||
r = ranges.pop()
|
||||
cur, idx = r['cur'], r['idx']
|
||||
|
||||
if cur == 'A':
|
||||
accepted.append(r)
|
||||
continue
|
||||
elif cur == 'R':
|
||||
continue
|
||||
|
||||
inst = workflows[cur][idx]
|
||||
if len(inst) == 4:
|
||||
letter = inst[0]
|
||||
value = inst[2]
|
||||
nxt = inst[3]
|
||||
ro = r[letter]
|
||||
r1, r2 = dict(r), dict(r)
|
||||
if inst[1] == 'smaller':
|
||||
r1[letter] = (ro[0], value - 1)
|
||||
r1['idx'] = 0
|
||||
r1['cur'] = nxt
|
||||
r2[letter] = (value, ro[1])
|
||||
r2['idx'] += 1
|
||||
elif inst[1] == 'greater':
|
||||
r1[letter] = (ro[0], value)
|
||||
r1['idx'] += 1
|
||||
r2[letter] = (value + 1, ro[1])
|
||||
r2['idx'] = 0
|
||||
r2['cur'] = nxt
|
||||
if r1[letter][1] >= r1[letter][0]:
|
||||
ranges.append(r1)
|
||||
if r2[letter][1] >= r2[letter][0]:
|
||||
ranges.append(r2)
|
||||
elif len(inst) == 1:
|
||||
r['cur'] = inst[0]
|
||||
r['idx'] = 0
|
||||
ranges.append(r)
|
||||
res = 0
|
||||
for a in accepted:
|
||||
r = 1
|
||||
for c in 'xmas':
|
||||
l, u = a[c]
|
||||
r *= (u + 1 - l)
|
||||
res += r
|
||||
return res
|
||||
|
||||
def main():
|
||||
DAY_INPUT = "i19.txt"
|
||||
|
||||
print("Example 1:", solve(Input(EXAMPLE)))
|
||||
return
|
||||
|
||||
print("Solution 1:", solve(Input(DAY_INPUT)))
|
||||
return
|
||||
# 25:00
|
||||
|
||||
print("Example 2:", solve(Input(EXAMPLE), True))
|
||||
return
|
||||
|
||||
print("Correct 2:", 167409079868000)
|
||||
print("Solution 2:", solve(Input(DAY_INPUT), True))
|
||||
# 120:00
|
||||
return
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user