| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546 |
- #!/usr/bin/env python3
- import sys
- from functools import reduce
- from itertools import product
- from operator import or_
- def parse(f):
- x_tr = str.maketrans('X1', '10')
- for line in f:
- left, right = line.rstrip().split(' = ')
- if left == 'mask':
- x = int(right.translate(x_tr), 2)
- ones = int(right.replace('X', '0'), 2)
- yield True, x, ones
- else:
- yield False, int(left[4:-1]), int(right)
- def run_v1(program):
- mem = {}
- and_mask = or_mask = 0
- for is_mask, a, b in program:
- if is_mask:
- and_mask = a
- or_mask = b
- else:
- mem[a] = b & and_mask | or_mask
- return sum(mem.values())
- def run_v2(program):
- mem = {}
- fluct_masks = []
- for is_mask, a, b in program:
- if is_mask:
- and_mask = ~(a | b)
- or_mask = b
- fl = [i for i in range(36) if a >> i & 1]
- fluct_masks = [reduce(or_, (b << i for b, i in zip(bits, fl)), 0)
- for bits in product((0, 1), repeat=len(fl))]
- else:
- for fluct_mask in fluct_masks:
- mem[a & and_mask | or_mask | fluct_mask] = b
- return sum(mem.values())
- program = list(parse(sys.stdin))
- print(run_v1(program))
- print(run_v2(program))
|