diff --git a/2020/day14_docking.py b/2020/day14_docking.py
new file mode 100644
index 0000000..2050d18
--- /dev/null
+++ b/2020/day14_docking.py
@@ -0,0 +1,81 @@
+import enum
+import functools
+import math
+import re
+from typing import List, Dict, Iterable
+
+
+def main(filename: str, expected_part_1: int = None, expected_part_2: int = None):
+ print(f"\n+ Running on {filename}")
+ with open(filename) as f:
+ instructions = f.read().strip().split("\n")
+
+ program = ProgramPart1(instructions)
+ program.run()
+ counter_part_1 = program.compute_memory_sum()
+
+ print(f"1. Found {counter_part_1}")
+ if expected_part_1:
+ assert expected_part_1 == counter_part_1
+
+ counter_part_2 = solve_part_2(instructions)
+ print(f"2. Found {counter_part_2}")
+ if expected_part_2:
+ assert expected_part_2 == counter_part_2
+
+
+Memory = Dict[str, str]
+
+
+class ProgramPart1:
+ def __init__(self, instructions: Iterable[str]):
+ self.memory = dict() # type: Memory
+ self.instructions = instructions
+ self.mask = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ self.mem_line_regex = re.compile(r"^mem\[(?P
\d+)] = (?P\d+)$")
+
+ def run(self):
+ for line in self.instructions:
+ self.run_line(line)
+
+ def compute_memory_sum(self):
+ int_base_2 = functools.partial(int, base=2)
+ return sum(map(int_base_2, self.memory.values()))
+
+ def run_line(self, line: str):
+ if "mask" in line:
+ self.update_mask(line)
+ else:
+ self.update_memory(line)
+
+ def update_mask(self, line: str):
+ self.mask = line.split(" = ")[1]
+
+ def update_memory(self, line: str):
+ match = self.mem_line_regex.match(line)
+ if not match:
+ raise RuntimeError("Memory line regex doesn't match")
+ groups = match.groupdict()
+ address = groups["address"]
+ value = int(groups["value"])
+ self.memory[address] = self.get_masked_value(value)
+
+ def get_masked_value(self, value: int) -> str:
+ binary_value = "{:036b}".format(value)
+ masked_value = []
+ for binary_bit, mask_bit in zip(binary_value, self.mask):
+ if mask_bit == "X":
+ masked_value.append(binary_bit)
+ else:
+ masked_value.append(mask_bit)
+
+ return "".join(masked_value)
+
+
+def solve_part_2(program: Iterable[str]) -> int:
+ return 0
+
+
+if __name__ == "__main__":
+ main("inputs/day14-test1", 165)
+ main("inputs/day14")
diff --git a/2020/inputs/day14 b/2020/inputs/day14
new file mode 100644
index 0000000..febb627
--- /dev/null
+++ b/2020/inputs/day14
@@ -0,0 +1,560 @@
+mask = X100110110X011000101000101XX11001X11
+mem[5201] = 1838761
+mem[32099] = 25747352
+mem[36565] = 72187
+mem[31494] = 369864
+mem[17260] = 3138
+mem[64903] = 91484814
+mask = 0X00100101000XX0011110X10110X100X010
+mem[54866] = 120526
+mem[57614] = 430839
+mem[17916] = 648
+mem[43192] = 325890
+mem[23626] = 313518443
+mem[45988] = 50484
+mask = 01001001X0001X00XXX110X010010XX0X001
+mem[60805] = 1352
+mem[37516] = 5942314
+mem[63169] = 237020309
+mem[31655] = 274507
+mask = 010011010001110000010000X101X0X11X01
+mem[49875] = 15349586
+mem[6956] = 13765452
+mem[675] = 886107857
+mask = 01000001X1XX11011X1111X111X000X01X11
+mem[2135] = 5930
+mem[1861] = 1009
+mem[62754] = 145160
+mem[1333] = 1153712
+mem[15455] = 7454
+mask = 01X01X011X0011X0X10110001X1X1000X110
+mem[53253] = 667716
+mem[47571] = 745817
+mem[48582] = 5810
+mem[3620] = 7851685
+mem[41836] = 14080244
+mem[39150] = 84103
+mask = 01001X01100X100010X111111X11100XX111
+mem[249] = 514
+mem[25687] = 48545
+mem[62083] = 208926
+mem[39872] = 2590
+mem[28491] = 267
+mem[25340] = 115744
+mem[31101] = 6781
+mask = 0100100100011101000XX001XX0010100X10
+mem[6053] = 6291996
+mem[37941] = 514441
+mem[22984] = 108425255
+mem[30540] = 127685
+mask = 000X100101011X1X1010X1011110XX10X1X0
+mem[42567] = 253905
+mem[45241] = 15790
+mem[57132] = 480344
+mem[29971] = 22597051
+mask = XXX0111110001100010X1X01X10X0000000X
+mem[44680] = 428361054
+mem[17571] = 4884
+mask = X1X001010X0111101X11X100X10100101100
+mem[55107] = 2922
+mem[8605] = 5742
+mem[63754] = 289191
+mask = 01101001010X11000110111X11000X01X000
+mem[48186] = 7310
+mem[30306] = 413
+mem[1980] = 538481
+mask = 010011011XX011X110011111101X01101X1X
+mem[45241] = 11454771
+mem[65349] = 36152803
+mem[62368] = 34863
+mem[26794] = 5220
+mask = 010X10XXX1001100011101X00X0110011110
+mem[15496] = 898
+mem[59847] = 32170699
+mem[5411] = 130682
+mem[27017] = 205172
+mem[48688] = 3072
+mask = 001X000X111X110000110XX0010100001110
+mem[17575] = 12630818
+mem[51454] = 28544
+mem[52745] = 45251
+mask = 000000010100X110X11101X101X1011010X1
+mem[49456] = 637756
+mem[63169] = 99927
+mem[50318] = 7599616
+mem[42115] = 48825
+mem[20469] = 5931716
+mem[56899] = 2884
+mask = 01XX100X0100X10001XX011111X000001XX0
+mem[45630] = 2305
+mem[28560] = 118602807
+mem[45644] = 52185
+mem[3682] = 56264
+mem[63201] = 237495702
+mem[63572] = 7683
+mem[24477] = 370
+mask = 01X0X0XX0X011100011110000X0XX00X1111
+mem[14028] = 3492
+mem[28452] = 213847
+mem[57663] = 203516
+mem[24701] = 45071697
+mem[30226] = 856135
+mem[59279] = 100557
+mask = 0110100001X0X1X0010XX1XX00X100000000
+mem[4237] = 60693
+mem[51454] = 56389
+mem[44364] = 12145
+mem[53190] = 3825966
+mask = 0X0010000X011X0011111001100010X10100
+mem[45988] = 84435
+mem[43613] = 171165
+mem[39150] = 2025
+mask = 000001010X111100111101001000X00X000X
+mem[7204] = 243074994
+mem[30540] = 2829011
+mem[16986] = 171341
+mask = 01101X0101001X101X1111110X0X01X0010X
+mem[40006] = 276307
+mem[50601] = 45
+mem[2907] = 7955
+mem[61049] = 14014170
+mem[20722] = 52156072
+mem[12299] = 1701485
+mem[4643] = 2041760
+mask = X1101000010X110X0111X011001101000000
+mem[29309] = 29638912
+mem[23626] = 127552394
+mem[39357] = 2743410
+mask = XXX01000000110001111101X101X1XX0XX01
+mem[32322] = 110798340
+mem[38758] = 20398089
+mem[62368] = 6402
+mem[12381] = 125762
+mem[34042] = 46630
+mask = 0X1X100X0X01100X11X11111101100100001
+mem[56680] = 52806
+mem[3416] = 5097254
+mem[21217] = 959
+mem[11134] = 22705
+mem[39515] = 607
+mem[31858] = 527794383
+mask = 011110010100X10001110111X0XXX00110X1
+mem[37752] = 3783
+mem[27543] = 180509
+mem[56503] = 26998899
+mem[33984] = 2996098
+mem[6471] = 16602683
+mem[18585] = 5056811
+mem[3477] = 16274
+mask = 010110011XXX110X01011XX11X0100110X00
+mem[43993] = 784
+mem[12295] = 412860764
+mem[62707] = 11253
+mem[27017] = 1813664
+mask = 1XX0X001010X1010101100X000X0100XX000
+mem[25364] = 640
+mem[35537] = 489258314
+mem[356] = 47335
+mem[46814] = 130
+mem[21071] = 32074
+mem[23980] = 1969160
+mem[43457] = 28765451
+mask = 0X0XX00110XX1X00X10111110011X01X1001
+mem[37516] = 3409
+mem[32451] = 486160
+mem[31704] = 494261
+mem[64905] = 489121330
+mask = 10001001X101111010X010X1X11X1001010X
+mem[19927] = 125979
+mem[16164] = 163616
+mem[41291] = 11806544
+mem[13074] = 22666
+mem[65160] = 1102
+mem[21338] = 53735104
+mask = 00X00101X10111XX111101XX10X111111100
+mem[44736] = 13061
+mem[62844] = 31422
+mem[4643] = 59264
+mem[45417] = 5454
+mask = X0001X010X001101011X11001XX000101000
+mem[33984] = 13200
+mem[15462] = 316464
+mem[2638] = 1434216
+mem[29044] = 1370180
+mem[57663] = 77699993
+mem[39191] = 9595034
+mask = 100X1X0X010111X011101011111111XX1000
+mem[60509] = 275540
+mem[65073] = 8066
+mem[64726] = 78129
+mem[15719] = 724
+mem[52499] = 43989105
+mem[57518] = 6805488
+mem[27827] = 1522993
+mask = 0X010110X011X100111X00000111X1110X10
+mem[395] = 16602
+mem[21477] = 62043769
+mem[24630] = 663408947
+mem[3983] = 31082032
+mem[30545] = 456250
+mask = 0100XX01X000X10X10011101100X11101X10
+mem[28174] = 110183887
+mem[9644] = 12911
+mem[62113] = 145
+mask = 010010X10000100100110000101X1XX11011
+mem[63016] = 127052
+mem[49130] = 37
+mem[25394] = 187810
+mem[29779] = 11708792
+mem[36144] = 1033
+mask = 00101001X10XX10X11111X1100000111X001
+mem[35746] = 498408
+mem[15462] = 7839193
+mem[5741] = 168870
+mask = 0010100100X011XX1111X1001001X1X10101
+mem[2256] = 10474689
+mem[57428] = 8228
+mem[34062] = 16609889
+mem[45031] = 106065
+mem[17162] = 138367053
+mem[23302] = 14262
+mask = 001100110X1X11XX110100X0010100XX1000
+mem[33186] = 1012027
+mem[34051] = 148436
+mem[4762] = 25019364
+mem[41825] = 102071658
+mem[32580] = 739
+mem[15455] = 151015
+mask = 01X1XX00X10001000100011001000000XX10
+mem[31330] = 300785
+mem[30222] = 206857068
+mem[27739] = 774225
+mem[47798] = 12155
+mem[57437] = 440075165
+mem[49892] = 58
+mem[44723] = 116116
+mask = 100X1X00000X100011X1X00100101X00010X
+mem[35368] = 5187
+mem[24769] = 1425443
+mem[62844] = 277
+mem[30729] = 11517370
+mask = 0110100X0010110111X10X111000X11011X1
+mem[63295] = 139
+mem[60805] = 381899
+mem[6956] = 3979616
+mem[12295] = 1828
+mask = 010010X10X00X00X00X11XX00001X1001X00
+mem[39150] = 459766
+mem[52621] = 1962
+mem[11891] = 5261559
+mask = X11011X11X00110001011X1X110010000000
+mem[48473] = 3539
+mem[13808] = 331
+mem[30016] = 676
+mem[9736] = 3140258
+mem[12233] = 388562584
+mem[42686] = 1048145655
+mem[26132] = 67723
+mask = 01001X0X010X0001001X10101111X10110X1
+mem[35042] = 230878861
+mem[8611] = 488144
+mem[4290] = 942073
+mem[12381] = 17121117
+mem[15011] = 225
+mem[8378] = 9255
+mask = 00001X0XX01X11X01101001101011110101X
+mem[49708] = 312037855
+mem[19488] = 93439469
+mem[57113] = 7931
+mem[29037] = 210754
+mask = 0100X001X0X01X0100110X11X110001110X1
+mem[8519] = 38940
+mem[49033] = 10564
+mem[58481] = 4187786
+mem[5201] = 230275712
+mem[39296] = 886
+mask = 1000100X010X11101X1011011X0110X11XXX
+mem[38587] = 50240362
+mem[42581] = 116256847
+mem[37181] = 4441034
+mem[16281] = 23027479
+mem[32451] = 71649158
+mem[33316] = 6511
+mask = 000001X11101111011X1X10X1X001X1X1000
+mem[26168] = 390
+mem[11548] = 29301
+mem[2731] = 3188615
+mask = 1100XX00X0X110001X111X000011X0X10001
+mem[32136] = 6436
+mem[46206] = 225594
+mem[33132] = 7862942
+mem[15264] = 198
+mask = 01001001000X1101000111011X0011XXX10X
+mem[33733] = 14993993
+mem[9905] = 246637292
+mem[6373] = 2090
+mem[53539] = 29386
+mask = 0X1010X1X01011XX11111100100XX110X00X
+mem[41520] = 452041
+mem[8605] = 43647
+mem[62764] = 3241680
+mask = 0X1X10X1010111X0X1110XXX00000110X001
+mem[38517] = 3338
+mem[52745] = 4455
+mem[33218] = 850605
+mem[20495] = 315451
+mask = 0XX0X001010X11X01X111X1101X11X101000
+mem[32284] = 615642818
+mem[62844] = 46924
+mem[31120] = 146622
+mem[21925] = 518931
+mem[29515] = 1112
+mem[31241] = 130404
+mem[9905] = 5469165
+mask = 01101000001X110X1101101110XX1X1XX101
+mem[46432] = 346428972
+mem[64522] = 218092103
+mem[42311] = 2316477
+mem[20060] = 565
+mem[62919] = 261004
+mem[50103] = 42134
+mask = 0101100101000100X1X01XX11X0X00111010
+mem[41199] = 48367827
+mem[40992] = 886149
+mem[19927] = 93429
+mask = 01001X01X0XX110X0XX1110X011110001101
+mem[40019] = 187824261
+mem[3416] = 35491
+mem[51276] = 173825792
+mask = X100100110001X000X11010X00001010X001
+mem[21071] = 3775434
+mem[41466] = 601899
+mem[29191] = 163888869
+mem[64981] = 1094832
+mem[36745] = 7560
+mem[44434] = 3179
+mem[5040] = 16142
+mask = 0X101X011XX011111111010100010X0X01X0
+mem[44140] = 22478
+mem[26863] = 31310307
+mem[56680] = 131716
+mem[3983] = 22050
+mask = 1X0X10010X011X1X101X1000X1100X000010
+mem[45724] = 5130
+mem[38747] = 147724
+mem[39515] = 58764331
+mask = 0X001101X10000010X1X00010XX001010101
+mem[50201] = 65493
+mem[44879] = 7688011
+mem[29782] = 85876639
+mem[63157] = 57556
+mask = 00X00001010111X010X1X01X0101X01010XX
+mem[37667] = 539
+mem[65058] = 928398
+mem[16037] = 2162946
+mask = X010100000X11X001111001011011001XX11
+mem[20601] = 689238135
+mem[62832] = 22132331
+mem[20030] = 421255
+mem[38454] = 4898563
+mask = 01101XX0000111X001111100011000X01111
+mem[40968] = 287372
+mem[32860] = 121630361
+mem[6956] = 54910
+mask = 01101001100X11X0010X0101101010001X11
+mem[52270] = 852273185
+mem[44434] = 5773
+mem[40591] = 363113
+mem[31075] = 550
+mem[1148] = 237482
+mask = 0110100000001100X111X111111010X00X10
+mem[9807] = 919
+mem[10050] = 284353
+mem[11553] = 99307
+mask = 11X1X0X0010001000101100X1XX10X100X10
+mem[51707] = 59769
+mem[17916] = 456671254
+mem[15968] = 74716184
+mem[61681] = 11534
+mask = 0X0010010000110X01X1X111X001X111100X
+mem[63572] = 19584
+mem[12382] = 54348210
+mem[7204] = 62681
+mem[58309] = 718
+mask = XX0X0X11X0XX1100X10110111101X1000101
+mem[19172] = 49321
+mem[3972] = 156574486
+mem[53411] = 371993
+mem[34118] = 1245490
+mem[63786] = 28834
+mem[44434] = 1679
+mask = 0X010XX1101111001101110X1X0X1X1000X0
+mem[65433] = 41829624
+mem[5383] = 3874764
+mem[58309] = 40586
+mem[34516] = 1861
+mask = 0X00100X000X1100111X0011100010011100
+mem[30691] = 6349
+mem[26045] = 2259746
+mem[35285] = 2525303
+mem[56918] = 64290918
+mem[34521] = 495146
+mem[41173] = 1892852
+mem[62708] = 2610505
+mask = X1001000010XX10001011X10101000011000
+mem[41877] = 606935473
+mem[10746] = 30201
+mem[7236] = 2402617
+mem[31075] = 394149597
+mem[62893] = 2808512
+mem[44723] = 5738170
+mem[61147] = 2124552
+mask = 01X0100X0X0X1100X1111X11X00X01X01001
+mem[9905] = 376
+mem[56967] = 457904468
+mem[55040] = 2448
+mem[65513] = 2222
+mem[25340] = 23079
+mem[39876] = 4874
+mem[38909] = 16667453
+mask = X0001X0X01011110101X10XX1X1X10X01100
+mem[19488] = 3061762
+mem[26132] = 292794
+mask = 010010X101X01001001110X000X1011X11X0
+mem[1980] = 12162025
+mem[37165] = 15333747
+mem[39210] = 152686
+mask = 01X010X0010XX100011110000X000XX00101
+mem[27917] = 944976
+mem[25099] = 11114
+mem[7777] = 577171
+mem[27080] = 16334871
+mem[14285] = 531
+mask = X1X0100001X01100X10X1111100X00111010
+mem[28216] = 2511
+mem[37165] = 7141
+mem[55924] = 439753
+mem[11901] = 464
+mem[38571] = 407
+mem[782] = 10823
+mask = 0XX00X01010111XX11111110XX010010000X
+mem[54749] = 360481
+mem[20495] = 5280
+mem[37684] = 6039
+mem[6345] = 2073116
+mem[63110] = 22301539
+mask = X0X1010110111100110X1001100X1X100100
+mem[20722] = 9600365
+mem[19084] = 76987
+mem[23777] = 740859
+mask = 001X000111X01X000X11X000110111101100
+mem[27917] = 52797296
+mem[57636] = 322
+mem[11553] = 70582
+mem[8605] = 30966411
+mem[25394] = 812862
+mem[48296] = 317
+mem[60466] = 1411129
+mask = X110000X0XXX11101111001X100110100000
+mem[33339] = 4981
+mem[40073] = 5710720
+mem[33814] = 13208
+mem[14664] = 1950645
+mem[35042] = 35994943
+mask = 10101000X0X1X0XXX1X1101011001100000X
+mem[61417] = 114327
+mem[26863] = 706549
+mem[5651] = 118955
+mask = 011X10000010110111X10111X1001100101X
+mem[7679] = 272716
+mem[24077] = 12277996
+mask = X11XX000010001X00X011X1111X001XX0000
+mem[46531] = 35092779
+mem[1116] = 11777757
+mem[5932] = 519743
+mem[36187] = 318
+mem[38758] = 718897339
+mask = 01001X0110001000X0010X010010X01000X0
+mem[31101] = 257
+mem[39813] = 30972074
+mem[23252] = 1761211
+mask = 0X10100X00X0110X1111X1111010X1001101
+mem[17132] = 2823025
+mem[62368] = 442239906
+mem[24553] = 339245
+mem[64751] = 66303
+mem[56967] = 870173
+mem[15383] = 342572184
+mem[1647] = 20517
+mask = 00001XX000X11X0011X110X110XX1X010101
+mem[16037] = 1478
+mem[33316] = 30615219
+mem[6729] = 209640491
+mask = 01001000X1X1X100X1110100000X1X011X01
+mem[62368] = 29355190
+mem[48784] = 1522851
+mem[26590] = 14698075
+mask = 0XX0X0011X00X0000X11011010011110X101
+mem[249] = 746
+mem[11553] = 236505210
+mem[38328] = 823888
+mem[58433] = 125568672
+mask = X000X0000101X1101X10110X000X00111100
+mem[37813] = 4058843
+mem[32745] = 9417061
+mask = 000XX110001111X01XX1XX01X00111110100
+mem[22103] = 2397
+mem[40229] = 47978173
+mem[3477] = 14703
+mem[8594] = 2471
+mem[22603] = 44648051
+mem[11340] = 25471
+mask = 000001X1010111001X11X1X1100XX0101X0X
+mem[41160] = 52
+mem[2907] = 827
+mem[15719] = 107392281
+mem[43537] = 19084747
+mem[53742] = 3326211
+mem[46206] = 51870
+mem[30694] = 6031208
+mask = 0X10100000011100111X11100010X1111X01
+mem[31885] = 3110667
+mem[40041] = 30422
+mask = 00XX0XX101X111XX11X10111001101001000
+mem[2874] = 10110
+mem[21776] = 28380745
+mem[32004] = 7076
+mem[9644] = 526
+mask = 011010110001X1000XX110X0X0110000X011
+mem[35281] = 4670
+mem[7204] = 115940579
+mem[58380] = 17616
+mem[40735] = 46877007
+mem[30986] = 20371
+mask = 0XX01001010010X100111010110001111X10
+mem[43046] = 2060276
+mem[20743] = 553391345
+mem[20821] = 3685352
+mem[43943] = 39969
+mask = 0010100101010X0011XXX01XX100XXX11111
+mem[29261] = 60453
+mem[63512] = 94339357
+mem[34827] = 18871625
+mem[52359] = 322200
+mem[38003] = 25491
+mem[24795] = 461240689
+mask = 0000010X01011100101X010100X1X1101010
+mem[26894] = 3512
+mem[1023] = 9354
+mask = 11010XXX100011001101011X1111011001X1
+mem[45476] = 4571
+mem[2838] = 7601404
+mem[30540] = 187
+mask = X1X01X01X000110001011X010X0111X01001
+mem[32944] = 381053
+mem[63110] = 7479218
+mem[59783] = 121082
+mem[56918] = 1237706
+mem[32355] = 472
+mem[44080] = 131839645
+mem[56680] = 38523
diff --git a/2020/inputs/day14-test1 b/2020/inputs/day14-test1
new file mode 100644
index 0000000..e15150a
--- /dev/null
+++ b/2020/inputs/day14-test1
@@ -0,0 +1,4 @@
+mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X
+mem[8] = 11
+mem[7] = 101
+mem[8] = 0