2020/14.py
def part2():
    """
    In this one, I converted to use stringly typed masks instead of the crazy bithacking
    that I did in Part 1.
    """
    mem = {}
    max_count_x = 0
    # this is just here to make my linter happy because it doesn't know that curmask is
    # going to be set on the first iteration of the loop.
    curmask = ""

    for line in lines:
        if rematch("mask.*", line):
            curmask = rematch("mask = (.*)", line).group(1)
        else:
            loc, val = map(int, rematch(r"mem\[(\d+)\] = (\d+)", line).groups())

            # Pad the memory access location so that it is the same size as the curmask.
            # This allows me to zip and not loose values.
            access = pbits(loc, len(curmask))

            # Compute  the result bits as a string (this allows us to have the Xs).
            result_bits = ""
            for access_loc_bit, curmask_bit in sizezip(access, curmask):
                if curmask_bit == "0":
                    result_bits += access_loc_bit
                elif curmask_bit == "1":
                    result_bits += "1"
                else:
                    result_bits += "X"

            # Compute all of the bit combos with itertools.product. This gives all of
            # the "permutations with replacement" of 0 and 1 of size N where N is the
            # number of Xs in the result.
            num_xs = result_bits.count("X")
            max_count_x = max(max_count_x, num_xs)
            for bit_combo in it.product("01", repeat=num_xs):
                # Compute the actual memory location to store the value to by going
                # through all of the bits in the result and if it's an X, using the
                # corresponding value in the bit_combo instead of X.
                real_loc = ""
                combo_idx = 0
                for b in result_bits:
                    if b in "01":
                        real_loc += b
                    else:
                        real_loc += bit_combo[combo_idx]
                        combo_idx += 1

                # Interpret it as binary
                mem[real_loc] = val

    print(
        "Max number of Xs in any given string: {} so only ever {} tuples out of\n"
        "    the call to `it.product`".format(max_count_x, 2 ** max_count_x)
    )
    return sum(mem.values())

    In this one, I converted to use stringly typed masks instead of the crazy bithacking
    that I did in Part 1.
    
In this one, I converted to use stringly typed masks instead of the crazy bithacking
that I did in Part 1.
In this one I converted to use stringly typed masks instead of the crazy bithacking that I did in Part 1 .
def part2():
    mem = {}
    max_count_x = 0
    curmask = ""
    for line in lines:
        if rematch("mask.*", line):
            curmask = rematch("mask = (.*)", line).group(1)
        else:
            loc, val = map(int, rematch(r"mem\[(\d+)\] = (\d+)", line).groups())
            access = pbits(loc, len(curmask))
            result_bits = ""
            for access_loc_bit, curmask_bit in sizezip(access, curmask):
                if curmask_bit == "0":
                    result_bits += access_loc_bit
                elif curmask_bit == "1":
                    result_bits += "1"
                else:
                    result_bits += "X"
            num_xs = result_bits.count("X")
            max_count_x = max(max_count_x, num_xs)
            for bit_combo in it.product("01", repeat=num_xs):
                real_loc = ""
                combo_idx = 0
                for b in result_bits:
                    if b in "01":
                        real_loc += b
                    else:
                        real_loc += bit_combo[combo_idx]
                        combo_idx += 1
                mem[real_loc] = val
    print(
        "Max number of Xs in any given string: {} so only ever {} tuples out of\n"
        "    the call to `it.product`".format(max_count_x, 2 ** max_count_x)
    )
    return sum(mem.values())
def part2 ( ) : mem = { } max_count_x = 0 curmask = "" for line in lines : if rematch ( "mask.*" , line ) : curmask = rematch ( "mask = (.*)" , line ) . group ( 1 ) else : loc , val = map ( int , rematch ( r"mem\[(\d+)\] = (\d+)" , line ) . groups ( ) ) access = pbits ( loc , len ( curmask ) ) result_bits = "" for access_loc_bit , curmask_bit in sizezip ( access , curmask ) : if curmask_bit == "0" : result_bits += access_loc_bit elif curmask_bit == "1" : result_bits += "1" else : result_bits += "X" num_xs = result_bits . count ( "X" ) max_count_x = max ( max_count_x , num_xs ) for bit_combo in it . product ( "01" , repeat = num_xs ) : real_loc = "" combo_idx = 0 for b in result_bits : if b in "01" : real_loc += b else : real_loc += bit_combo [ combo_idx ] combo_idx += 1 mem [ real_loc ] = val print ( "Max number of Xs in any given string: {} so only ever {} tuples out of\n" "    the call to `it.product`" . format ( max_count_x , 2 ** max_count_x ) ) return sum ( mem . values ( ) )
In this one, I converted to use stringly typed masks instead of the crazy bithacking
that I did in Part 1.
In this one I converted to use stringly typed masks instead of the crazy bithacking that I did in Part 1 .
"""
    In this one, I converted to use stringly typed masks instead of the crazy bithacking
    that I did in Part 1.
    """ # this is just here to make my linter happy because it doesn't know that curmask is # going to be set on the first iteration of the loop. # Pad the memory access location so that it is the same size as the curmask. # This allows me to zip and not loose values. # Compute  the result bits as a string (this allows us to have the Xs). # Compute all of the bit combos with itertools.product. This gives all of # the "permutations with replacement" of 0 and 1 of size N where N is the # number of Xs in the result. # Compute the actual memory location to store the value to by going # through all of the bits in the result and if it's an X, using the # corresponding value in the bit_combo instead of X. # Interpret it as binary