day 14


the input for this is a list of bitmasks followed by memory locations and values to put in those locations (after the appropriate masks are applied).

for both parts we start off by just reading in the file, and making an empty dictionary to contain these values in the appropriate locations:

# input
with open('14.txt', 'r') as file:
    input = file.read()
# turn the input into a list - this has either a mask or a mem
input_list = list(input.split('\n'))
# have the mem as a dict
mem_dict = {}

we then iterate over the lines in the input list, and if this starts with 'mask' then we use the value after it as the bit mask; if this is a memory value and location - in the form mem[mem_loc] = mem_value - then we get the value as a binary string with the same length as the mask. we split the mask and the binary string (mem_bin) into a list of their characters by using the list() function, and then we iterate over these characters, changing the value to the one in the bitmask (or leaving it the same if there's an X at that point).

after the end of this for loop, we add together all the values in mem_dict to get the answer to the puzzle.

for line in input_list:
    if line[:4] == 'mask': # if this is a mask line
        mask = line[7:] # store the mask - str after 'mask = '
    elif line[:3] == 'mem': # if this is a mem line
        # e.g. line = 'mem[25226] = 65531297'
        # find where the close bracket is
        close_bracket = line.find(']')
        mem_loc = int(line[4:close_bracket])
        # mem_loc = 25226
        # find where the = is
        equals = line.find('=')
        mem_val = int(line[(equals+1):])
        # mem_val = 65531297
        # get mem_val as binary
        mem_bin = bin(mem_val)[2:]
        # slice to remove the '0b'
        # mem_bin = '11111001111110110110100001'
        # add on leading zeroes if needed
        if len(mask) > len(mem_bin):
            mem_bin = ('0' * (len(mask) - len(mem_bin))) + mem_bin
        # mem_bin = '000000000011111001111110110110100001'
        # split into characters
        mask_chars = list(mask)
        memb_chars = list(mem_bin)
        # apply mask
        for i in range(0,len(mask)):
            # change memb_char if not X
            if not mask_chars[i] == 'X':
                memb_chars[i] = mask_chars[i]
        # overwrite mem_bin with the concatenation of memb_chars
        mem_bin = ''.join(memb_chars)
        # get int from str
        mem_val = int(mem_bin,2)
        # add to dict
        mem_dict[mem_loc] = mem_val
# mem filled
print('sum of mem values (part a): ' + str(sum(list(mem_dict.values()))))

for the second part, we have the same kind of setup, except the mask is now applied to the memory locations, with 0 meaning the bit is unchanged, 1 meaning the bit is set to 1, and X meaning the bit can be either 0 or 1; the value is then written to all possible memory locations. getting a list of all possible memory locations (mem_locs) is implemented by starting with the list [''] and iterating over the characters of the memory location (with X meaning it can be 0 or 1) in memb_chars. if this character is a 0 or 1, then the character is added to the end of every string in mem_locs; if this character is X, then we take two copies of mem_locs, add 0 to the end of all of the strings in one, and 1 to the end of all of the strings in the other, and then make mem_locs the combination of these two lists.

once we have this list of memory locations, we take mem_loc to be the integer value corresponding to each bitstring, and then set mem_dict[mem_loc] = mem_val (write the value to all possible memory locations). as before, we print the sum of all values in this dictionary at the end of the loop.

for line in input_list:
    if line[:4] == 'mask': # if this is a mask line
        mask = line[7:] # store the mask - str after 'mask = '
    elif line[:3] == 'mem': # if this is a mem line
        # same as before:
        close_bracket = line.find(']')
        mem_loc = int(line[4:close_bracket])
        equals = line.find('=')
        mem_val = int(line[(equals+1):]) 
       mem_bin = bin(mem_loc)[2:]
        if len(mask) > len(mem_bin):
            mem_bin = ('0' * (len(mask) - len(mem_bin))) + mem_bin
        mask_chars = list(mask)
        memb_chars = list(mem_bin)
        # apply mask
        for i in range(0,len(mask)):
            # floating if X (either 0 or 1)
            if mask_chars[i] == 'X':
                memb_chars[i] = 'X'
            # set bit as 1 if 1
            elif mask_chars[i] == '1':
                memb_chars[i] = '1'
        # get list of all possible mem_locs
        mem_locs = ['']
        for i in range(0,len(mask)):
            # if this is a floating bit
            if memb_chars[i] == 'X':
                # add 0 to every string
                mems0 = []
                for mem_bin in mem_locs:
                    mems0.append(mem_bin + '0')
                # add 1 to every string
                mems1 = []
                for mem_bin in mem_locs:
                    mems1.append(mem_bin + '1')
                # make both of these lists together the new list
                mem_locs = mems0 + mems1
            else: # this is '0' or '1'
                # append this to all lists in the string
                for j in range(0,len(mem_locs)):
                    mem_locs[j] = mem_locs[j] + memb_chars[i]
        for mem_bin in mem_locs:
            # get int from str
            mem_loc = int(mem_bin,2)
            # add to dict
            mem_dict[mem_loc] = mem_val
# mem filled
print('sum of mem values (part b): ' + str(sum(list(mem_dict.values()))))

this one was okay, just a little finicky and there's not much to explain besides exactly what the code does

Files

14a.py 1.7 kB
Dec 14, 2020
14b.py 2.1 kB
Dec 14, 2020

Get aoc 2020

Leave a comment

Log in with itch.io to leave a comment.