14_docking.py 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. #!/usr/bin/env python3
  2. import sys
  3. from functools import reduce
  4. from itertools import product
  5. from operator import or_
  6. def parse(f):
  7. x_tr = str.maketrans('X1', '10')
  8. for line in f:
  9. left, right = line.rstrip().split(' = ')
  10. if left == 'mask':
  11. x = int(right.translate(x_tr), 2)
  12. ones = int(right.replace('X', '0'), 2)
  13. yield True, x, ones
  14. else:
  15. yield False, int(left[4:-1]), int(right)
  16. def run(program, v2):
  17. mem = {}
  18. and_mask = or_mask = 0
  19. fluct = []
  20. for is_mask, a, b in program:
  21. if v2 and is_mask:
  22. and_mask = ~a & ~b
  23. or_mask = b
  24. fluct = [i for i in range(36) if (a >> i) & 1]
  25. elif v2:
  26. for bits in product((0, 1), repeat=len(fluct)):
  27. fluct_bits = (bit << i for bit, i in zip(bits, fluct))
  28. fluct_mask = reduce(or_, fluct_bits, 0)
  29. mem[a & and_mask | or_mask | fluct_mask] = b
  30. elif is_mask:
  31. and_mask = a
  32. or_mask = b
  33. else:
  34. mem[a] = b & and_mask | or_mask
  35. return sum(mem.values())
  36. program = list(parse(sys.stdin))
  37. print(run(program, False))
  38. print(run(program, True))