選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

p19.py 1.2KB

1年前
1234567891011121314151617181920212223242526272829303132333435363738394041
  1. import math
  2. def consume(cc, label, step):
  3. if label in 'AR':
  4. return label
  5. else:
  6. op, new = workflows[label][step]
  7. if eval(op, None, cc):
  8. return consume(cc, new, 0)
  9. else:
  10. return consume(cc, label, step + 1)
  11. text = open(0).read()
  12. aa, bb = text.split('\n\n')
  13. workflows = {}
  14. for line in aa.splitlines():
  15. key, rest = line.split('{')
  16. workflows[key] = [('True:' + ln).split(':')[-2:] for ln in rest[:-1].split(',')]
  17. candidates = [{k[0]: int(k[2:]) for k in ln[1:-1].split(',')} for ln in bb.splitlines()]
  18. print(sum(sum(cc.values()) for cc in candidates if consume(cc, 'in', 0) == 'A'))
  19. def consume2(cc, label, step):
  20. if label in 'AR':
  21. yield math.prod(len(vs) for vs in cc.values()), label
  22. else:
  23. op, new = workflows[label][step]
  24. if op == 'True':
  25. yield from consume2(cc, new, 0)
  26. else:
  27. k = op[0]
  28. vs = {v for v in cc[k] if eval(op, None, {k: v})}
  29. yield from consume2(cc | {k: vs}, new, 0)
  30. yield from consume2(cc | {k: cc[k] - vs}, label, step + 1)
  31. bop = {k: set(range(1, 4000 + 1)) for k in 'xmas'}
  32. print(sum(m for m, label in consume2(bop, 'in', 0) if label == 'A'))