Advertisement
Guest User

Advent of Code Day 14

a guest
Dec 14th, 2020
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.59 KB | None | 0 0
  1. """Day 14 of Advent of Code 2020 Solution"""
  2. from collections.abc import MutableMapping
  3.  
  4.  
  5. class BinArray(MutableMapping):
  6.     def __init__(self, mask=None, mem_len=36):
  7.         if mask:
  8.             self._mask = mask
  9.         self.mem_len = mem_len
  10.         self.mem = dict()
  11.  
  12.     @property
  13.     def mask(self):
  14.         return self._mask
  15.  
  16.     @mask.setter
  17.     def mask(self, mask):
  18.         _mask = {}
  19.         for i, v in enumerate(reversed(mask)):
  20.             if v != "X":
  21.                 _mask[i] = v
  22.         self._mask = _mask
  23.  
  24.     def __getitem__(self, item):
  25.         return self.mem[item]
  26.  
  27.     def __setitem__(self, key, value):
  28.         if self.mask:
  29.             value = bin(value)[2:].zfill(self.mem_len)
  30.             new_value = []
  31.             for i, v in enumerate(reversed(value)):
  32.                 if i in self.mask:
  33.                     new_value.append(self.mask[i])
  34.                 else:
  35.                     new_value.append(v)
  36.             self.mem[key] = "".join([*reversed(new_value)])
  37.         else:
  38.             self.mem[key] = value
  39.  
  40.     def __delitem__(self, key):
  41.         del self.mem[key]
  42.  
  43.     def __iter__(self):
  44.         for key in self.mem.keys():
  45.             yield key
  46.  
  47.     def dec_values(self):
  48.         for k in self:
  49.             yield int(self[k], 2)
  50.  
  51.     def __len__(self):
  52.         return len(self.mem)
  53.  
  54.  
  55. class DecoderChip:
  56.     def __init__(self):
  57.         self.mem = dict()
  58.         self._mask = None
  59.         self.mem_len = 36
  60.  
  61.     @property
  62.     def mask(self):
  63.         return self._mask
  64.  
  65.     @mask.setter
  66.     def mask(self, mask):
  67.         self._mask = "".join([*reversed(mask)])
  68.  
  69.     def __setitem__(self, key, value):
  70.         mem_locations = [""]
  71.         key = bin(key)[2:].zfill(self.mem_len)
  72.         for i, v in enumerate(reversed(key)):
  73.             if self.mask[i] == "X":
  74.                 mem_floats_zero = mem_locations.copy()
  75.                 for j, mem_float in enumerate(mem_floats_zero):
  76.                     mem_floats_zero[j] += "0"
  77.                 mem_floats_one = mem_locations.copy()
  78.                 for j, mem_float in enumerate(mem_floats_one):
  79.                     mem_floats_one[j] += "1"
  80.                 mem_locations = mem_floats_zero + mem_floats_one
  81.             elif self.mask[i] == "1":
  82.                 for j, mem_float in enumerate(mem_locations):
  83.                     mem_locations[j] += "1"
  84.             else:
  85.                 for j, location in enumerate(mem_locations):
  86.                     mem_locations[j] += v
  87.         mem_locations = ["".join([*reversed(location)]) for location in mem_locations]
  88.         for location in mem_locations:
  89.             self.mem[location] = value
  90.  
  91.  
  92. def part_a(file_location):
  93.     mem = BinArray()
  94.     with open(file_location, "r") as f:
  95.         for line in f.readlines():
  96.             line = line.split(" = ")
  97.             if line[0] == "mask":
  98.                 mem.mask = line[1].strip()
  99.             else:
  100.                 mem_slot, value = line[0][4:-1], int(line[1])
  101.                 mem[mem_slot] = value
  102.     return sum([*mem.dec_values()])
  103.  
  104.  
  105. def part_b(file_location):
  106.     decoder = DecoderChip()
  107.     with open(file_location, "r") as f:
  108.         for line in f.readlines():
  109.             line = line.split(" = ")
  110.             if line[0] == "mask":
  111.                 decoder.mask = line[1].strip()
  112.             else:
  113.                 mem_slot, value = int(line[0][4:-1]), int(line[1])
  114.                 decoder[mem_slot] = value
  115.     return sum([*decoder.mem.values()])
  116.  
  117.  
  118. if __name__ == "__main__":
  119.     file_location = r"data/day14.txt"
  120.     print(part_a(file_location))
  121.     print(part_b(file_location))
  122.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement