advent2020/fourteen.py

61 lines
1.3 KiB
Python
Executable File

#!/usr/bin/env python3
from functools import reduce
import sys
def tpl(l):
me, rest = l.split(' = ') # e.g.
return me, rest
def mask(m, n):
orm = reduce(lambda a, b: a*2 + (b == '1'), (0, *list(m)))
andm = reduce(lambda a, b: a*2 + (b != '0'), (1, *list(m)))
return (n & andm | orm)
def bmask(m, n):
orm = reduce(lambda a, b: a*2 + (b == '1'), (0, *list(m)))
res = (n | orm)
return res
def setmem(d, adr, ghost, val):
if ghost == []:
return
g = ghost[0]
orm = 2**g
andm = ~(2**g)
d[adr|orm] = val
d[adr&andm] = val
setmem(d, adr|orm, ghost[1:], val)
setmem(d, adr&andm, ghost[1:], val)
def address(s):
a = int(s[4:-1])
return a
def ghosts(m):
g = [(35 - i) for i, j in enumerate(m) if j == 'X']
return g
fn = sys.argv[1] if len(sys.argv) > 1 else 'input%s' % 14
with open(fn) as f:
lines = [l.strip() for l in f.readlines()]
_, m = tpl(lines[0])
t = [tpl(l) for l in lines]
d = {}
for a, b in t:
if a == 'mask':
m = b
else:
d[a] = mask(m, int(b))
print(sum(d.values()))
d = {}
for a, b in t:
if a == 'mask':
m = b
else:
setmem(d, bmask(m, address(a)), ghosts(m), int(b))
print(sum(d.values()))