Advent of Code: Day #14 - Docking Data

14th of December 2020 |

5 - 6 minutes

Introduction

I really enjoyed todays puzzle! All about Bit Masking and Binary.

Task One

Given an list input of either Mask = 36 Bit number OR mem[address] = number run the instructions and report the sum of all numbers in memory.

Reading in the data

I split the data up and if the item was a new mask I added it to the dataset in the format ["mask", new_mask]. If it was a memory address I removed the text and added the data in the format [address, data].

Python Copy
def read_data(path):
dataset = []

with open(path) as f:
for line in f.readlines():
tmp = line.strip().split(" = ")
if tmp[0] == "mask":
dataset.append(["mask", list(tmp[1])])
else:
mem_address = int(tmp[0][tmp[0].index("[") + 1: -1])
dataset.append([mem_address, int(tmp[1])])
return dataset

The Solution

Solving part one was quite simple. If the current instruction is a mask then we update the mask, otherwise we apply the mask to the data and then assign the value to the memory dictionary. To end we return the sum of the memory dictionary's values.

Python Copy
def task_one(instructions):
memory = {}
current_mask = ["X" for _ in range(36)]

for current_instruction, data in instructions:
if current_instruction == "mask":
current_mask = data
else:
binary = list(format(data, "036b"))
for index, char in enumerate(current_mask):
if char != "X":
binary[index] = char

memory[current_instruction] = int("".join(binary), 2)

return sum(memory.values())

Task Two

The Solution

In task two it is reveled that the mask actually applies to the memory address, and instead of ignoring X's they now represent 'Floating Bits' that take on every permeation of 0 and 1. I.E if your memory address has 2 X's you will end up with 4 new addresses as there are 4 different combination of 0 and 1 in pairs of 2. (0, 0), (0, 1), (1, 0) and (1, 1). I used the product function from itertools to compute all of these permutations then looped through the memory address and updated the values! I'm always impressed at what itertools has to offer!

Python Copy
from itertools import product

def task_two(instructions):
memory = {}
current_mask = ["X" for _ in range(36)]

for current_instruction, data in instructions:
if current_instruction == "mask":
current_mask = data
else:
# Turn the memory address into binary
binary = list(format(current_instruction, "036b"))
for index, char in enumerate(current_mask):
if char != "0":
binary[index] = char
adr = binary

# Create all permutations for the floating bits
addresses = []
x_amount = adr.count("X")
indices = [index for index, x in enumerate(adr) if x == "X"]
for combo in product("01", repeat=x_amount):
new_adr = adr
for index, c in enumerate(combo):
new_adr[indices[index]] = c
addresses.append(int("".join(new_adr), 2))

for address in addresses:
memory[address] = data

return sum(memory.values())


Leaderboard Code: 353270-1fc6ef28

Github Repository A link to the github repo containing all the days.

main.py A direct download of the main.py script

2.2Kb