Skip to content

Commit a9bf15e

Browse files
author
tuukkasarvi
committedDec 17, 2020
Day 14
1 parent 9828e8a commit a9bf15e

File tree

2 files changed

+756
-0
lines changed

2 files changed

+756
-0
lines changed
 

‎data/input_14.txt

+544
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,544 @@
1+
mask = 1100X10X01001X111001X00010X00100X011
2+
mem[24821] = 349
3+
mem[34917] = 13006
4+
mem[53529] = 733
5+
mem[50289] = 245744
6+
mem[23082] = 6267
7+
mask = 011X1X00X100100XXXX11100X0000100X010
8+
mem[21316] = 14188354
9+
mem[53283] = 7137
10+
mem[57344] = 62358
11+
mem[63867] = 9443
12+
mask = XXX00X0X0X000101000010001001X011X100
13+
mem[24644] = 116
14+
mem[48236] = 73606120
15+
mem[10510] = 38322
16+
mask = X1X110000X0X100X1101X00111010X011X10
17+
mem[34997] = 31342
18+
mem[26072] = 2268501
19+
mem[5252] = 632
20+
mem[7236] = 22768
21+
mem[49071] = 551093395
22+
mask = 01XX100001001X00XX1XX101100X00101001
23+
mem[54837] = 244218
24+
mem[21783] = 11585
25+
mem[21099] = 76905
26+
mem[2378] = 53200
27+
mem[26270] = 417292
28+
mem[45806] = 620
29+
mask = X11X0111X100X10100X0X1X011X10100111X
30+
mem[58750] = 183290
31+
mem[43104] = 86138
32+
mem[19509] = 11175103
33+
mem[49328] = 267886858
34+
mask = 000X110X01X0110100101X0X00XX00010001
35+
mem[59931] = 59583
36+
mem[32104] = 883
37+
mem[15538] = 243291
38+
mask = 001X1101010X11010XXX01010111101X00X1
39+
mem[8242] = 108187354
40+
mem[65087] = 38969853
41+
mem[48863] = 63153
42+
mem[25959] = 230061422
43+
mem[43740] = 368377
44+
mem[58841] = 4055593
45+
mem[59380] = 59386
46+
mask = 110110010100XX11XX010100100110001100
47+
mem[7020] = 447178
48+
mem[36813] = 2655
49+
mem[31309] = 1748
50+
mem[24822] = 5683403
51+
mem[60917] = 6812
52+
mask = 0XX1010X01X011X1X010X001110110100010
53+
mem[44478] = 1586539
54+
mem[39782] = 949
55+
mem[54286] = 96566
56+
mem[14466] = 99
57+
mem[20192] = 18086
58+
mem[3717] = 79648
59+
mem[58752] = 40328
60+
mask = 100X1X001X00111111X1100100X11XX0X101
61+
mem[18878] = 2450507
62+
mem[5564] = 1664611
63+
mem[9704] = 116868
64+
mem[21119] = 102749
65+
mem[25549] = 2173
66+
mem[63519] = 7948355
67+
mem[9402] = 29593133
68+
mask = X1101100110X10001111101X0X00X1000010
69+
mem[24578] = 16594035
70+
mem[12855] = 62817
71+
mem[19754] = 204831
72+
mem[39912] = 587039668
73+
mem[20004] = 1492295
74+
mem[17243] = 5531
75+
mem[1316] = 28121178
76+
mask = 001111XX01001X01001X111110X1101010X1
77+
mem[29079] = 3819301
78+
mem[43580] = 3021873
79+
mem[12717] = 91478
80+
mask = 111XX10X010X1011XX0100000000X0001X0X
81+
mem[21612] = 1342337
82+
mem[13794] = 6460
83+
mem[63974] = 79096
84+
mem[61231] = 79
85+
mem[52748] = 548989
86+
mask = 110X1X01010XXXX1X0010000101X011001X0
87+
mem[7150] = 129613326
88+
mem[2629] = 19221
89+
mem[34913] = 5720809
90+
mask = 0XX0X0X00100X1X00111011X111X10X11101
91+
mem[14506] = 808939
92+
mem[22097] = 3682116
93+
mem[45143] = 70886840
94+
mem[11000] = 823928
95+
mem[45922] = 709192
96+
mem[38124] = 21830062
97+
mask = 00XXX10X01001101X010XX10X1X100100010
98+
mem[54703] = 154976
99+
mem[12855] = 187248782
100+
mem[65457] = 28101
101+
mem[15696] = 2295684
102+
mem[30880] = 1247718
103+
mem[45160] = 515441
104+
mask = 1X110101010011X1100110X0001X01001100
105+
mem[57318] = 100074
106+
mem[47449] = 4621
107+
mem[59319] = 50563
108+
mem[41125] = 37890243
109+
mask = X11X0101010011X11001X010110100000010
110+
mem[50289] = 5524
111+
mem[42244] = 3206413
112+
mem[56334] = 869121
113+
mem[38672] = 1475
114+
mem[15747] = 203
115+
mem[24920] = 87767798
116+
mask = X111110X000010X1X00100011100X0011X11
117+
mem[21588] = 451
118+
mem[23953] = 46630
119+
mem[14775] = 49711378
120+
mem[50858] = 2467
121+
mask = 1101100001001X0110011001XXX11111X001
122+
mem[55659] = 1545765
123+
mem[6437] = 31978856
124+
mem[39782] = 14103777
125+
mem[36553] = 11829098
126+
mem[381] = 1092062
127+
mem[8934] = 730472
128+
mem[2555] = 1825500
129+
mask = 0XX0100X010010001X111X00100X01001X11
130+
mem[2219] = 43334
131+
mem[22560] = 1622449
132+
mem[43084] = 947441529
133+
mask = 110X1000010X1X1X100101010110000XX0X0
134+
mem[36928] = 489523
135+
mem[28368] = 13289
136+
mask = X111X10101001101X0XX1X0011X0000001XX
137+
mem[18457] = 3703
138+
mem[3623] = 32246635
139+
mem[24559] = 80719
140+
mem[58118] = 8905129
141+
mem[16253] = 45786863
142+
mem[40870] = 495305
143+
mem[9309] = 259478546
144+
mask = 01111100X1001XX10010X1100X1010010000
145+
mem[5294] = 197088
146+
mem[44504] = 10557956
147+
mem[59142] = 116862
148+
mask = 1X01X10100XXX0101XX1101X1000001011X1
149+
mem[16259] = 434323408
150+
mem[62326] = 739075
151+
mem[46819] = 13021
152+
mem[60917] = 2384
153+
mask = X1X01X0001001000001011010000X1101100
154+
mem[21341] = 70959125
155+
mem[62908] = 762
156+
mem[34493] = 484
157+
mem[17428] = 31
158+
mask = 01011011010110X10111110X00X1110010XX
159+
mem[18984] = 3776829
160+
mem[57419] = 6347092
161+
mask = 01X11101010011010010X0XX11X101X01100
162+
mem[3581] = 47227
163+
mem[15034] = 148249156
164+
mem[39328] = 32020553
165+
mem[45580] = 921
166+
mask = 1X11110X0000X0111001XX001X01100X1010
167+
mem[65437] = 31942299
168+
mem[41279] = 52981019
169+
mem[22939] = 30
170+
mask = 11011X0X01001XX11X010X01001111XX1X00
171+
mem[49334] = 2124
172+
mem[3052] = 75699
173+
mem[56099] = 206
174+
mask = X10X110001XX1011100X1001X0000XX01110
175+
mem[16214] = 194247445
176+
mem[5064] = 6545
177+
mem[24889] = 334318
178+
mem[60668] = 613191688
179+
mem[13452] = 2759371
180+
mask = XXX001X1010001010X0000X001X1X11011X0
181+
mem[41278] = 202539349
182+
mem[17818] = 6496568
183+
mem[51738] = 793135
184+
mask = 01110X1X0X00X10000X000X1011110001X00
185+
mem[54203] = 102262453
186+
mem[47434] = 11948539
187+
mem[4065] = 1955823
188+
mem[5838] = 116726352
189+
mem[22858] = 770
190+
mask = 1X0111010X10X01X100110001111X0X00X11
191+
mem[2486] = 828784
192+
mem[45704] = 52334
193+
mem[25505] = 7455952
194+
mem[35622] = 2191372
195+
mem[43475] = 1724531
196+
mem[51269] = 231866
197+
mask = 10011000XX001X1111XXXX0X00111000010X
198+
mem[1849] = 42419
199+
mem[4574] = 1532276
200+
mem[24053] = 414769
201+
mask = 1111X1X1XX0X10X110XX10001101101X1111
202+
mem[50131] = 380577
203+
mem[14034] = 324
204+
mem[43433] = 468143
205+
mem[57359] = 918
206+
mem[32101] = 671267
207+
mem[10229] = 779186
208+
mask = 110X1100010X11X110XX1101X01101011000
209+
mem[50062] = 1717353
210+
mem[44599] = 213984
211+
mem[2474] = 270288
212+
mem[25959] = 947
213+
mem[14725] = 59
214+
mem[43580] = 1510
215+
mask = 011XX10101001101X00111001101X0001100
216+
mem[56933] = 226
217+
mem[13318] = 4614
218+
mem[30661] = 15820
219+
mask = X1011100XX0X10111000X001110X00010X10
220+
mem[43263] = 15614563
221+
mem[58584] = 4208089
222+
mem[44934] = 1045
223+
mem[8892] = 7322
224+
mask = 1X011000X10010X111010001XX111001XX1X
225+
mem[49868] = 246
226+
mem[5838] = 22365009
227+
mem[41002] = 23308
228+
mem[20933] = 135967
229+
mem[28178] = 191447
230+
mem[12921] = 12366
231+
mask = 111X0X0X0100110100XX00000X0001000000
232+
mem[37981] = 3749401
233+
mem[26391] = 5633
234+
mem[32104] = 36834
235+
mem[44124] = 3460632
236+
mem[5838] = 491004585
237+
mask = 01000X1101X0010X0100X11011011111X0X0
238+
mem[23993] = 9267350
239+
mem[51536] = 1866241
240+
mem[40301] = 264185
241+
mem[65174] = 1500904
242+
mem[30449] = 2040
243+
mem[11574] = 31366391
244+
mask = X1X11101X1X010111X01100X0X100X00X101
245+
mem[51781] = 12168
246+
mem[39202] = 21507
247+
mask = 11011X00010X1X1X10011000XX1X01X00X10
248+
mem[14042] = 2091313
249+
mem[54126] = 926
250+
mem[54056] = 380624
251+
mem[4492] = 58611931
252+
mem[14287] = 2682945
253+
mask = 011000000X0X1X010X1101X0100000111000
254+
mem[37035] = 8382057
255+
mem[5086] = 105635
256+
mem[59782] = 287247
257+
mem[59842] = 261015
258+
mem[55905] = 427749005
259+
mem[38951] = 116871701
260+
mask = 011XXXX001001X0X001011X10100X0010100
261+
mem[37224] = 240173934
262+
mem[7233] = 4620173
263+
mem[11642] = 53937442
264+
mem[25130] = 31578
265+
mem[27305] = 19855
266+
mask = 01110111010011010X101X010X01111X10X0
267+
mem[9117] = 80452
268+
mem[45949] = 66133382
269+
mem[58118] = 431847
270+
mem[45227] = 31859837
271+
mem[12227] = 12785
272+
mem[10370] = 3992241
273+
mask = 011X01010X00X101X000101XX100X100X0X0
274+
mem[3584] = 98035933
275+
mem[48508] = 24604
276+
mask = 01101110010010X1001011X1X10000XX1X00
277+
mem[32223] = 13600
278+
mem[17788] = 30410813
279+
mask = 11X0110X0X00100000X011110101X1010000
280+
mem[54352] = 3305565
281+
mem[33020] = 56159
282+
mem[58750] = 3553365
283+
mask = 01110X0X010011010010100000000001X10X
284+
mem[45320] = 86117954
285+
mem[56412] = 32488
286+
mem[44120] = 27915
287+
mask = 1111110X0100X0010001X0101X0110111111
288+
mem[1600] = 3494
289+
mem[15191] = 8051858
290+
mem[4831] = 514
291+
mem[52749] = 3554802
292+
mem[14870] = 5452
293+
mask = X0X110X011001011110111000X11XX011010
294+
mem[32924] = 343831204
295+
mem[37938] = 206
296+
mem[29100] = 4279
297+
mask = 111X1101X11X101110X1110010100000000X
298+
mem[51565] = 21744022
299+
mem[17959] = 984
300+
mem[51269] = 546739474
301+
mask = X11X11000100110100100100010X110XX100
302+
mem[60489] = 1801861
303+
mem[10306] = 661
304+
mem[51002] = 1120331
305+
mem[4803] = 21542674
306+
mem[26350] = 878
307+
mem[42540] = 79468437
308+
mem[56396] = 6518705
309+
mask = 01XXX0XX010011X1X11111000X0011101X00
310+
mem[22955] = 1087
311+
mem[24644] = 31210240
312+
mem[11638] = 1408
313+
mem[22097] = 31493533
314+
mem[61231] = 2476899
315+
mask = X1011X011100101X11011100X010X0001101
316+
mem[56933] = 112988
317+
mem[60092] = 16076531
318+
mem[55659] = 668286721
319+
mem[56710] = 8215281
320+
mem[49668] = 5991824
321+
mem[49216] = 2918850
322+
mask = X001010101001111X010100X111X00100111
323+
mem[37025] = 17025
324+
mem[42119] = 410077231
325+
mask = 111X1101010X10011010X0X1011010001X11
326+
mem[31309] = 15349
327+
mem[47328] = 245527268
328+
mem[29215] = 1790
329+
mem[54165] = 6329067
330+
mem[11618] = 1311552
331+
mem[11994] = 15416
332+
mem[43900] = 4424
333+
mask = 00110X00X1011X000010X01100010101100X
334+
mem[31645] = 471
335+
mem[41596] = 13507488
336+
mem[11528] = 25929919
337+
mem[5643] = 56515
338+
mem[52143] = 74146
339+
mask = 0X11X1XX0100110X0010101011X1X1X01X00
340+
mem[4526] = 129045325
341+
mem[16253] = 15510
342+
mem[58841] = 114430082
343+
mem[63068] = 1155009
344+
mem[24644] = 95502013
345+
mask = 0110111001XX11000X1011001100XX0000X1
346+
mem[5333] = 7007
347+
mem[10355] = 3824
348+
mem[55659] = 33270617
349+
mem[61541] = 64962
350+
mem[51738] = 5209
351+
mem[44372] = 408
352+
mask = 0XX0111X01001X00011000101X0X00100010
353+
mem[42157] = 28376452
354+
mem[28513] = 51126906
355+
mem[43084] = 5419180
356+
mem[1997] = 54636
357+
mem[55504] = 3986
358+
mem[53253] = 14463148
359+
mask = X1110101X1000101100XX010010101110100
360+
mem[42226] = 3486504
361+
mem[54837] = 3033
362+
mem[15314] = 2651212
363+
mask = 0111001X010X110000X0110100110001X001
364+
mem[19828] = 38571
365+
mem[55362] = 120
366+
mem[41125] = 297069
367+
mem[63867] = 760277
368+
mem[22858] = 1756
369+
mem[54703] = 2820113
370+
mask = 0011X10101001101X0101X0110X0X0XX1111
371+
mem[56317] = 14975
372+
mem[60301] = 27507
373+
mem[17408] = 929
374+
mem[30115] = 7362
375+
mem[51269] = 13459
376+
mem[4803] = 162982952
377+
mask = 0111X1110100110100100110X1X0100011X1
378+
mem[2066] = 1018
379+
mem[9704] = 3359
380+
mem[17252] = 1200
381+
mem[11567] = 452882913
382+
mem[55807] = 420485632
383+
mask = 01011001110010111X011101XX1001XX1100
384+
mem[5641] = 7642797
385+
mem[18280] = 394199
386+
mem[55988] = 3777121
387+
mem[16857] = 75304
388+
mem[31220] = 17483158
389+
mask = X1011X01010100X110010000X00000101100
390+
mem[6958] = 73282287
391+
mem[6856] = 10312
392+
mem[1997] = 225131
393+
mem[36291] = 3200306
394+
mem[53139] = 6364
395+
mem[52857] = 488
396+
mask = 0X111100010X1X01001X010110X1X0111000
397+
mem[32210] = 44165292
398+
mem[61837] = 742353
399+
mem[47689] = 217901
400+
mask = 1111X10101001101X01111001X011000X111
401+
mem[1600] = 5283945
402+
mem[31412] = 227843745
403+
mem[3623] = 4853
404+
mem[21537] = 390
405+
mem[4405] = 1966
406+
mem[20470] = 18461
407+
mem[11567] = 393918381
408+
mask = 011001XX0X00X101X0X010100X0100111110
409+
mem[11528] = 1832756
410+
mem[43104] = 3039
411+
mem[21774] = 17789
412+
mem[47052] = 55655944
413+
mem[8626] = 3587
414+
mem[19085] = 735520
415+
mem[33906] = 1155
416+
mask = 1X0111000100X0011001X100101XX100101X
417+
mem[22097] = 46921
418+
mem[44609] = 12686579
419+
mem[37643] = 642
420+
mask = 0X001111010011X00XXX1010110000101011
421+
mem[54063] = 68442463
422+
mem[40578] = 7777
423+
mem[42404] = 355257
424+
mem[35709] = 440
425+
mem[61541] = 256096
426+
mask = 01001101011XX1X1101110001001X0000001
427+
mem[3584] = 16367
428+
mem[34903] = 7097
429+
mem[15295] = 238225
430+
mask = 00011011X1X0X001011XX110001101010001
431+
mem[47295] = 354843
432+
mem[23995] = 2140
433+
mem[57817] = 5421
434+
mem[41082] = 1355669
435+
mask = 1111X10101001X01X00XX01X1X1101X111X1
436+
mem[47377] = 172432
437+
mem[33686] = 52658909
438+
mask = 00X101X1010X1X000X1X01011101010X100X
439+
mem[60202] = 123593
440+
mem[46408] = 224836575
441+
mem[32157] = 8489804
442+
mem[30035] = 833772
443+
mem[10370] = 115684
444+
mask = 0X110000X1001XX100X01101110000010100
445+
mem[20388] = 32592482
446+
mem[53340] = 1787
447+
mem[55220] = 59958
448+
mem[6882] = 1363889
449+
mask = X00X010X01011XXXX0X101111100X1000001
450+
mem[56171] = 14491218
451+
mem[6723] = 143479
452+
mem[3167] = 466068
453+
mask = 1111110101X01XX110X11X00101000000101
454+
mem[17959] = 37575
455+
mem[64234] = 28252682
456+
mem[49216] = 434
457+
mask = 01111111X10011010010111X10X1001X0X0X
458+
mem[30726] = 5341
459+
mem[15854] = 1712
460+
mem[28248] = 492
461+
mask = 01011011X10X1101X11X1XX0X000X01001X0
462+
mem[49829] = 780701
463+
mem[9292] = 2918293
464+
mem[25072] = 247151
465+
mask = 0101100X01XX1101011XXX010010X1111001
466+
mem[19232] = 8569
467+
mem[54272] = 75036
468+
mem[54165] = 5018
469+
mem[31355] = 75073
470+
mem[9949] = 577427
471+
mem[30208] = 7439
472+
mask = 1X11XX01XX001X0110001010100001011000
473+
mem[9223] = 278171
474+
mem[14010] = 7098
475+
mask = 011111010X00110110X1XX00011X00000111
476+
mem[52261] = 52124331
477+
mem[39202] = 206235
478+
mem[45806] = 927
479+
mask = 0100X101X1X1XX0110X110001000X1000X11
480+
mem[58118] = 560
481+
mem[33171] = 204326670
482+
mem[51319] = 67953886
483+
mem[51237] = 10958
484+
mem[56614] = 7267273
485+
mask = 1XX0XX000101101X10X1X110100100001101
486+
mem[43771] = 2817
487+
mem[27887] = 274574
488+
mem[63850] = 107
489+
mask = X010111101001100011000XX1011X1101X10
490+
mem[30088] = 63233721
491+
mem[30726] = 605150
492+
mem[56614] = 48162
493+
mem[11271] = 2038084
494+
mask = X0X10110X100110100101X1111000001X10X
495+
mem[24920] = 989
496+
mem[59782] = 151549707
497+
mem[22082] = 7033941
498+
mem[22671] = 330574441
499+
mem[5252] = 1859
500+
mask = 0011110001X01100001XXX10111101X1X001
501+
mem[12192] = 47533
502+
mem[18902] = 118818
503+
mem[24826] = 19391580
504+
mem[3918] = 710
505+
mem[53370] = 19365460
506+
mem[49665] = 14466588
507+
mask = 0X11X101010011011011X110101100X001X0
508+
mem[23829] = 31936270
509+
mem[15854] = 13849536
510+
mem[29208] = 3999149
511+
mem[37128] = 13918
512+
mem[3328] = 259186933
513+
mask = 1X1X1X01010X110110111X000X0001000100
514+
mem[2629] = 55317
515+
mem[49216] = 881
516+
mem[40870] = 1619590
517+
mask = X1001XX10101000110011X0010X00110001X
518+
mem[3918] = 16125795
519+
mem[2919] = 13852
520+
mem[18470] = 7583882
521+
mask = 001101000X0X110XX0101011110X01001001
522+
mem[51858] = 157
523+
mem[4120] = 103247344
524+
mem[13914] = 423240
525+
mem[61736] = 159857
526+
mask = 0X011011010X1X0101111110XX0010XX00X1
527+
mem[61289] = 75040
528+
mem[43263] = 107031474
529+
mask = 11111X010100110X0X0010X011X100011101
530+
mem[29419] = 4825
531+
mem[16760] = 16715
532+
mem[42563] = 1981
533+
mem[40827] = 616757
534+
mem[51565] = 353
535+
mask = 010X10X00X00110X111X110X000XX0111101
536+
mem[2967] = 442177
537+
mem[18301] = 37578
538+
mem[56358] = 682
539+
mem[39237] = 59986049
540+
mem[2456] = 108546
541+
mask = 00100X0XX10011X1XX101X111100000XX001
542+
mem[6578] = 469499
543+
mem[60824] = 1460
544+
mem[50713] = 7725506

‎day_14.py

+212
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
"""
2+
https://adventofcode.com/2020/day/14
3+
4+
1.
5+
Execute the initialization program. What is the sum of all values left in memory after it completes?
6+
7+
2. Execute the initialization program using an emulator for a version 2 decoder chip.
8+
What is the sum of all values left in memory after it completes?
9+
"""
10+
from abc import ABC, abstractmethod
11+
import re
12+
from copy import deepcopy
13+
14+
filename = "data/input_14.txt"
15+
16+
17+
class Command(ABC):
18+
def __init__(self, data):
19+
self.parse(data)
20+
21+
@abstractmethod
22+
def parse(self):
23+
pass
24+
25+
@abstractmethod
26+
def execute(self, executor):
27+
pass
28+
29+
30+
class SetMaskCommand(Command):
31+
def parse(self, data):
32+
self.mask = data[(data.find("=") + 1):].strip()
33+
34+
def execute(self, executor):
35+
executor.set_mask(self.mask)
36+
37+
38+
class WriteToMemory(Command):
39+
def parse(self, data):
40+
self.key = int(re.compile(r"mem\[(\d+)\]").search(data).group(1))
41+
self.value = int(re.compile(r"= (\d+)$").search(data).group(1))
42+
43+
def execute(self, executor):
44+
executor.write_to_memory(self.key, self.value)
45+
46+
47+
class Executor:
48+
mask_length = 36
49+
50+
def __init__(self, lines):
51+
self.commands = [self.parse_command(line) for line in lines]
52+
self.mask = None
53+
self.memory = {}
54+
55+
def set_mask(self, mask):
56+
self.mask = mask
57+
58+
@staticmethod
59+
def mask_bit(bit, mask_char):
60+
if mask_char == "X":
61+
return bit
62+
elif mask_char in ["0", "1"]:
63+
return mask_char
64+
else:
65+
raise ValueError("Unknown mask_char %s" % mask_char)
66+
67+
def apply_mask(self, value):
68+
value_36_bits = (("0" * self.mask_length) + bin(value)[2:])[-self.mask_length:]
69+
masked_value = "".join([self.mask_bit(bit, m) for (bit, m) in zip(value_36_bits, self.mask)])
70+
masked_value = int(masked_value, 2)
71+
return masked_value
72+
73+
def write_to_memory(self, key, value):
74+
self.memory[key] = self.apply_mask(value)
75+
76+
@staticmethod
77+
def parse_command(line):
78+
if line.startswith("mask"):
79+
command = SetMaskCommand(line)
80+
elif line.startswith("mem"):
81+
command = WriteToMemory(line)
82+
else:
83+
raise ValueError("Unknown command: %s!" % line)
84+
return command
85+
86+
def execute_all(self):
87+
for command in self.commands:
88+
command.execute(self)
89+
90+
91+
def part1():
92+
with open(filename) as fp:
93+
lines = [line.strip("\n") for line in fp]
94+
executor = Executor(lines)
95+
executor.execute_all()
96+
print("Answer: %d" % (sum(executor.memory.values())))
97+
98+
99+
class Memory:
100+
def __init__(self, address_length):
101+
self.address_length = address_length
102+
self.memory = {}
103+
104+
def set_minus(self, address1, address2):
105+
""" returns set: address1 - address2 """
106+
assert len(address1) == len(address2)
107+
address1 = list(address1)
108+
address2 = list(address2)
109+
# Replace "X" in address2 by values in address1. This subset of address2 can only intersect with address1
110+
address2 = [address2[i] if (address2[i] in ["0", "1"]) else address1[i] for i in range(self.address_length)]
111+
intersect = all([
112+
(address1[i] == address2[i]) or (address1[i] == "X") for i in range(self.address_length)
113+
if (address2[i] in ["0", "1"])
114+
])
115+
if not intersect:
116+
return ["".join(address1)]
117+
temp = [i for i in range(self.address_length) if (address1[i] == "X") and (address2[i] in ["0", "1"])]
118+
if len(temp) == 0: # address2 covers address1 totally
119+
return [""] # empty set
120+
first_X_in_1_not_in_2 = min(temp)
121+
# Set first "X" address1 to opposite of 0/1 value in address2
122+
not_intersecting1 = deepcopy(address1)
123+
not_intersecting1[first_X_in_1_not_in_2] = str(abs(int(address2[first_X_in_1_not_in_2]) - 1)) # 0->1 and 1->0
124+
remainder1 = deepcopy(address1)
125+
# In other branch set it equal. For this branch, use recursion to find out set minus
126+
remainder1[first_X_in_1_not_in_2] = address2[first_X_in_1_not_in_2]
127+
return ["".join(not_intersecting1)] + self.set_minus(remainder1, address2)
128+
129+
def write(self, address, value):
130+
addresses_in_memory = list(self.memory.keys())
131+
set_minuses = [self.set_minus(a, address) for a in addresses_in_memory]
132+
# Remove empty sets "":
133+
set_minuses = [[a for a in s if a != ""] for s in set_minuses]
134+
# Update existing memory:
135+
for i, s in enumerate(set_minuses):
136+
# Remove old address: value
137+
val = self.memory[addresses_in_memory[i]]
138+
del self.memory[addresses_in_memory[i]]
139+
# Rewrite val to address space not intersecting with new value
140+
for a in s:
141+
self.memory[a] = val
142+
# Insert new overwriting value
143+
self.memory[address] = value
144+
145+
def get_address_sum(self, address):
146+
number_of_addresses = 2**(address.count("X"))
147+
return number_of_addresses * self.memory[address]
148+
149+
def get_sum(self):
150+
return sum([self.get_address_sum(a) for a in self.memory.keys()])
151+
152+
153+
class Executor2:
154+
mask_length = 36
155+
156+
def __init__(self, lines):
157+
self.commands = [self.parse_command(line) for line in lines]
158+
self.mask = None
159+
self.memory = Memory(address_length=36)
160+
161+
def set_mask(self, mask):
162+
self.mask = mask
163+
164+
@staticmethod
165+
def mask_bit(bit, mask_char):
166+
if mask_char == "0":
167+
return bit
168+
elif mask_char in ["1", "X"]:
169+
return mask_char
170+
else:
171+
raise ValueError("Unknown mask_char %s" % mask_char)
172+
173+
def apply_mask(self, value):
174+
value_36_bits = (("0" * self.mask_length) + bin(value)[2:])[-self.mask_length:]
175+
masked_value = "".join([self.mask_bit(bit, m) for (bit, m) in zip(value_36_bits, self.mask)])
176+
return masked_value
177+
178+
def write_to_memory(self, address, value):
179+
masked_address = self.apply_mask(address)
180+
self.memory.write(masked_address, value)
181+
182+
@staticmethod
183+
def parse_command(line):
184+
if line.startswith("mask"):
185+
command = SetMaskCommand(line)
186+
elif line.startswith("mem"):
187+
command = WriteToMemory(line)
188+
else:
189+
raise ValueError("Unknown command: %s!" % line)
190+
return command
191+
192+
def execute_all(self):
193+
for i, command in enumerate(self.commands):
194+
print(i)
195+
command.execute(self)
196+
197+
def get_memory_sum(self):
198+
return self.memory.get_sum()
199+
200+
201+
def part2():
202+
with open(filename) as fp:
203+
lines = [line.strip("\n") for line in fp]
204+
executor = Executor2(lines)
205+
executor.execute_all()
206+
print("Answer: %d" % executor.get_memory_sum())
207+
208+
209+
if __name__ == "__main__":
210+
part1()
211+
print("*****")
212+
part2()

0 commit comments

Comments
 (0)
Please sign in to comment.