-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathday14.py
executable file
·121 lines (95 loc) · 2.35 KB
/
day14.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env python3
from utils.all import *
advent.setup(2020, 14)
fin = advent.get_input()
# fin = io.StringIO('''\
# mask = 000000000000000000000000000000X1001X
# mem[42] = 100
# mask = 00000000000000000000000000000000X0XX
# mem[26] = 1
# ''')
eprint(*fin, sep=''); fin.seek(0, 0)
timer_start()
lines = get_lines(fin)
mem = [0] * 1000000
for l in lines:
if l.startswith('mask'):
l = l[len('mask = '):].strip()
override = {}
for i, c in enumerate(l[::-1]):
if c == '1':
override[i] = 1 << i
elif c == '0':
override[i] = 0
# eprint(override)
elif l.startswith('mem'):
addr, v = re.findall(r'mem\[(\d+)\] = (\d+)', l)[0]
addr, v = int(addr), int(v)
# eprint(addr, v)
for o in override:
res = (v & (0xfffffffff - (1 << o))) + override[o]
# eprint(bin(v).rjust(40))
# eprint(bin((0xfffffffff - (1 << o))).rjust(40))
# eprint(bin(res).rjust(40))
# eprint()
mem[addr] = res
v = mem[addr]
else:
assert False
# for i, x in enumerate(mem[:3]):
# print(i, ':', bin(x).rjust(40))
ans = sum(mem)
advent.print_answer(1, ans)
mem = {}
from itertools import product
# Oh almighty gods of programming forgive me for my immortal sins
def write_mem(addr, value, mask):
orig = addr
power = 0
for k, v in mask.items():
if v == 'X':
power += 1
else:
addr = addr | v
addr = list(bin(addr)[2:].rjust(36, '0'))
for i in range(36):
if i in mask and mask[i] == 'X':
addr[35-i] = 'X'
n = 2 ** power
str_addr = ''.join(addr)
# eprint(bin(orig)[2:].rjust(36, '0'))
# eprint(str_addr)
# eprint('---- n:', n)
for comb in range(n):
a = addr[:]
i = -1
# eprint('c:', bin(comb)[2:].rjust(power, '0'))
for b in bin(comb)[2:].rjust(power, '0'):
i = str_addr.find('X', i + 1)
if b == '1':
a[i] = '1'
else:
a[i] = '0'
a = ''.join(a)
a = int(a, 2)
mem[a] = value
# eprint('m[{:036b}] = {:036b}'.format(a, value))
for l in lines:
if l.startswith('mask'):
l = l[len('mask = '):].strip()
override = {}
for i, c in enumerate(l[::-1]):
if c == '1':
override[i] = 1 << i
elif c == 'X':
override[i] = 'X'
elif l.startswith('mem'):
addr, v = re.findall(r'mem\[(\d+)\] = (\d+)', l)[0]
addr, v = int(addr), int(v)
write_mem(addr, v, override)
else:
assert False
# for i, x in mem.items():
# print(i, ':', bin(x).rjust(40))
ans2 = sum(mem.values())
advent.print_answer(2, ans2)