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
Get aoc 2020
aoc 2020
not a mod, just some code
Status | Released |
Category | Other |
Author | riv |
Tags | advent-of-code, advent-of-code-2020, python |
Leave a comment
Log in with itch.io to leave a comment.