Advent of Code: Day #14 - Docking Data
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].
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.
def task_one(instructions):memory = {}current_mask = ["X" for _ in range(36)]for current_instruction, data in instructions:if current_instruction == "mask":current_mask = dataelse:binary = list(format(data, "036b"))for index, char in enumerate(current_mask):if char != "X":binary[index] = charmemory[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!
from itertools import productdef task_two(instructions):memory = {}current_mask = ["X" for _ in range(36)]for current_instruction, data in instructions:if current_instruction == "mask":current_mask = dataelse:# Turn the memory address into binarybinary = list(format(current_instruction, "036b"))for index, char in enumerate(current_mask):if char != "0":binary[index] = charadr = binary# Create all permutations for the floating bitsaddresses = []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 = adrfor index, c in enumerate(combo):new_adr[indices[index]] = caddresses.append(int("".join(new_adr), 2))for address in addresses:memory[address] = datareturn sum(memory.values())
Links
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