Exemple #1
0
def solution():
    bingo = get_input("input.prod").split('\n\n')
    drawn_nums = clean_calling_numbers(bingo[0])

    playing_boards = get_clean_boards(bingo[1:])

    for i in range(4):
        playing_boards = call_number(playing_boards, drawn_nums[i])

    winner = -1
    last_number_called = -1
    for num in drawn_nums[4:]:
        playing_boards = call_number(playing_boards, num)

        winner = check_for_winner(playing_boards)
        if winner > -1:
            last_number_called = num
            break

    winning_board = playing_boards[winner]

    sum_ = 0
    for row in winning_board:
        for num in row:
            if not num[1]:
                sum_ += num[0]

    return sum_ * last_number_called
Exemple #2
0
def get_product() -> int:
    '''
    The puzzle was to get the product of multiple routes. This helper function
    keeps track of, and then returns, the product.
    '''
    tree_map = get_input()
    slopes = [{
        'rise': 1,
        'run': 1
    }, {
        'rise': 1,
        'run': 3
    }, {
        'rise': 1,
        'run': 5
    }, {
        'rise': 1,
        'run': 7
    }, {
        'rise': 2,
        'run': 1
    }]

    product = 1
    for slope in slopes:
        product *= count_trees(slope['rise'], slope['run'], tree_map)

    return product
Exemple #3
0
def b_plot(files, ax, n_i, max_energy, msize, marker):
    """Plot alpha as a function of B"""
    values = []
    count = 0
    avg_deltaE = 0
    for f in files:
        b, d, n = get_input(f)
        max_e = find_max_e(f) if max_energy else 0
        if not max_energy:
            regex = r"""alpha_max_e_"""
            if re.compile(regex).search(f):
                continue
        if int(n) == n_i and max_energy == max_e:
            values.append([b, np.asscalar(np.loadtxt(f))])
            if max_energy:
                avg_deltaE += max_e
            else:
                avg_deltaE += np.loadtxt(f.replace('alpha', 'stable'))[1]
            count += 1
    if not count:
        print('No values for N =', n_i, 'and max energy', max_energy)
        return
    avg_deltaE = avg_deltaE / count
    print('Found', count, 'values for N =', n_i, 'and avg deltaE', avg_deltaE)
    # Plot the results
    ax.plot(np.array(values)[:, 0],
            np.array(values)[:, 1],
            linestyle='',
            label=r'$\Delta E\approx' + '{:.2f}'.format(avg_deltaE) + ', N=' +
            str(n_i) + '$',
            markersize=msize,
            marker=marker)
Exemple #4
0
def debug_program() -> int:
    '''
    We were told that the program bug was that exactly one operation was
    flipped, and that it was either a NOP to a JMP, or a JMP to a NOP.
    We'll iterate by line number, and for the given line in the program, first
    copy the program, then check the operation at the line, flip it if it is
    NOP or JMP. Then execute the program, and make sure it does not get caught
    in an infinite loop. We were told the program would only execute each
    instruction once, so the first repeat is considered an infinite loop.
    Return the accumulator value of the successfully run program.
    '''
    program = get_input()

    for line_number in range(len(program)):
        program_copy = program.copy()

        (op, value, _) = parse_instruction(program_copy[line_number])

        if op == 'acc':
            continue

        # Flip operation and write new instruction
        op = 'jmp' if op == 'nop' else 'nop'
        program_copy[line_number] = op + ' ' + str(value)

        accumulator = execute_program(program_copy)
        if accumulator > 0:
            return accumulator

    return -1
Exemple #5
0
def solve(n_tiles):
    data = get_input('input.prod')

    G = []
    for line in data:
        G.append([int(x) for x in line])
    R = len(G)
    C = len(G[0])
    DR = [-1, 0, 1, 0]
    DC = [0, 1, 0, -1]

    D = [[None for _ in range(n_tiles * C)] for _ in range(n_tiles * R)]
    Q = [(0, 0, 0)]
    while Q:
        (dist, r, c) = heapq.heappop(Q)
        if r < 0 or r >= n_tiles * R or c < 0 or c >= n_tiles * C:
            continue

        val = G[r % R][c % C] + (r // R) + (c // C)
        while val > 9:
            val -= 9
        rc_cost = dist + val

        if D[r][c] is None or rc_cost < D[r][c]:
            D[r][c] = rc_cost
        else:
            continue
        if r == n_tiles * R - 1 and c == n_tiles * C - 1:
            break

        for d in range(4):
            rr = r + DR[d]
            cc = c + DC[d]
            heapq.heappush(Q, (D[r][c], rr, cc))
    return D[n_tiles * R - 1][n_tiles * C - 1] - G[0][0]
Exemple #6
0
def exectue_program() -> int:
    '''
    This will execute the given program (puzzle input), and keep track of
    the accumulator value. Then it will return the accumulator value at the
    first repeated instruction.
    '''
    program = get_input()

    accumulator = line_number = 0
    while line_number < len(program):
        (op, value, was_executed) = parse_instruction(program[line_number])

        if was_executed:
            break

        program[line_number] += ' executed'

        if op == 'acc':
            accumulator += value
            line_number += 1
        elif op == 'jmp':
            line_number += value
        else:
            line_number += 1

    return accumulator
Exemple #7
0
def find_contiguous_subset():
    '''
    Given our input for part 1, we found an number that didn't fit the
    given criteria. We are then told that there exists a contiguous set
    of numbers in the input that will add to the invalid number. However,
    we were not told the subset size that will sum to the number. Starting
    with a set of 2, we'll loop though the input to find a subset of
    consecutive numbers that sum to the invalid number, incrementing the
    size of the subset with each loop.
    '''
    values = get_input()
    invalid = find_invalid_number(values)

    subset_length = 2
    while subset_length <= len(values):
        itr = 0

        while itr + subset_length <= len(values):
            contiguous_subset = values[itr:itr + subset_length]

            if sum(contiguous_subset) == invalid:
                low, high = get_min_max(contiguous_subset)
                return low + high

            itr += 1

        subset_length += 1
Exemple #8
0
def get_octopi_map():
    data = get_input("input.prod")

    o_map = list()
    for datum in data:
        o_map.append([int(flash_level) for flash_level in datum])

    return o_map
Exemple #9
0
def solution():
    polymer, rules_raw = get_input("input.prod").split("\n\n")

    rules = parse_rules(rules_raw)

    frequencies = count_characters(polymer, rules)

    return max(frequencies.values()) - min(frequencies.values())
Exemple #10
0
def solution():
    initial_points, instructions = get_input("input.prod").split("\n\n")

    paper = place_initial(initial_points)
    instr_set = parse_instructions(instructions)

    paper = follow_instructions(paper, [instr_set[0]])

    return count_dots(paper)
Exemple #11
0
def day_18():
    equations = get_input().splitlines()

    sum_ = 0
    for equation in equations:
        equation = resolve_parens(equation)
        sum_ += int(calculate(equation))

    return sum_
Exemple #12
0
def solution():
    polymer, rules_raw = get_input("input.prod").split("\n\n")

    rules = parse_rules(rules_raw)

    for _ in range(10):
        polymer = insertion(polymer, rules)

    return calc_difference(polymer)
Exemple #13
0
def solution():
    depths = [int(x) for x in get_input("input.prod")]

    total = 0
    for i in range(4, len(depths)):
        if depths[i] > depths[i - 3]:
            total += 1

    return total
Exemple #14
0
def day_10():
    values = get_input()

    dict = {1: 0, 2: 0, 3: 0}
    values.sort()
    dict[values[0]] += 1
    for itr in range(len(values) - 1):
        dict[values[itr + 1] - values[itr]] += 1
    dict[3] += 1
    return dict[1] * dict[3]
Exemple #15
0
def solution():
    parens = get_input("input.prod")

    position = 0
    floor = 0
    for char in parens:
        floor += 1 if char == "(" else -1
        position += 1

        if floor == -1:
            return position
Exemple #16
0
def solution():
    fish = get_input("input.prod")

    for day in range(80):
        for i in range(len(fish)):
            fish[i] -= 1

            if fish[i] == -1:
                fish[i] = 6
                fish.append(8)

    return len(fish)
Exemple #17
0
def find_seat_equilibrium():
    seat_map = get_input()

    while True:
        next_seats = build_next_seat_map(seat_map)

        if next_seats == seat_map:
            break
        else:
            seat_map = next_seats

    return count_seats_occupied(seat_map)
Exemple #18
0
def get(return_eigv=False,
        return_ket=False,
        return_index=False,
        return_cmax=False,
        return_H=False):
    """Return the eigenvalues and optionally the eigenvectors,
    the number operator form of the states(ket), the state index of the states,
    the max coefficient index and the Hamiltonian"""
    # Load files
    H = readH('npz')  # read the Hamiltonian
    # Save to npz to save sapce
    if not isfile('hamilt.npz'):
        np.savez_compressed('hamilt.npz', H=H)
        remove('hamilt.bin')
    b, d, n = get_input()
    n = int(n)
    index = np.array([(n1, n2) for n1 in range(n) for n2 in range(n - n1)])
    # Get eigenvalues and eigenvectors
    if isfile('eigensystem.npz'):
        print('Used cached result for: B =', b, 'D =', d, 'N =', n)
        eigensystem = np.load('eigensystem.npz')
        E = eigensystem['E']
        eigenvectors = eigensystem['eigenvectors']
    else:
        start = timer()
        E, eigenvectors = linalg.eigh(H, turbo=True)
        end = timer()
        print('Diagonalisation for N =', n, ':', end - start, 'seconds')
        # Save the results
        np.savez_compressed('eigensystem.npz', E=E, eigenvectors=eigenvectors)

    eigenvectors = np.transpose(eigenvectors)  # each eigenvector is on one row

    # max coefficient in eigenvector
    c_max = np.empty(eigenvectors.shape[0], dtype=int)

    # The index of the largest coefficient
    for i in range(eigenvectors.shape[0]):
        c_max[i] = np.argmax(np.abs(eigenvectors[i]))

    results = (E, )
    if return_eigv:
        results += (eigenvectors, )
    if return_ket:
        results += (index[c_max], )
    if return_index:
        results += (index, )
    if return_cmax:
        results += (c_max, )
    if return_H:
        results += (H, )
    return results
Exemple #19
0
def solution():
    inputs = get_input("input.prod")

    lowest = 999999999
    for i in range(min(inputs), max(inputs) + 1):
        sum_ = 0
        for inp in inputs:
            sum_ += abs(i - inp)

        if sum_ < lowest:
            lowest = sum_

    return lowest
Exemple #20
0
def solution():
    signals = get_input("input.prod")

    sum_ = 0
    for signal in signals:
        codes, output = signal.split(" | ")
        codes = list(map(''.join, map(sorted, codes.split())))
        output = list(map(''.join, map(sorted, output.split())))

        digits = decode_wires(codes)

        sum_ += get_output(digits, output)

    return sum_
Exemple #21
0
def solution():
    inputs = get_input("input.prod")

    lowest = 999999999
    for i in range(min(inputs), max(inputs) + 1):
        sum_ = 0
        for inp in inputs:
            # The sum of integers between the two: (n * (n + 1)) / 2
            fuel_burned = int((abs(i - inp) * (abs(i - inp) + 1)) / 2)
            sum_ += fuel_burned

        if sum_ < lowest:
            lowest = sum_

    return lowest
Exemple #22
0
def generate_dist_map():
    data = get_input("input.prod")

    dist_map = {}
    city_col = []
    for datum in data:
        [cities, distance] = datum.split(' = ')
        [city1, city2] = cities.split(' to ')
        if city1 not in city_col:
            city_col.append(city1)
        if city2 not in city_col:
            city_col.append(city2)
        dist_map[cities] = int(distance)
        dist_map[city2 + " to " + city1] = int(distance)

    return city_col, dist_map
Exemple #23
0
def solution():
    height_map = []

    # Generate 2d array of heights
    for height in get_input("input.prod"):
        height_map.append([int(x) for x in height])

    # Collect local minimums to sum later
    local_mins = []
    for x in range(len(height_map)):
        for y in range(len(height_map[0])):
            if is_low_point(height_map, x, y):
                local_mins.append(height_map[x][y])

    # len(local_mins) is the +1 on each min
    return sum(local_mins) + len(local_mins)
Exemple #24
0
def anyone_answered_yes():
    '''
    We received a collection of questionnaires, where the groups of people
    are separated by a blank line, and an individual's answer is separated
    by a newline. We iterate through, and find all questions that were
    answered 'yes' (exist in the questionnaire for the individual) for the
    whole group. Then, return the sum of questions answered by each group.
    '''
    questionnaires = get_input()

    count = 0
    for questionnaire in questionnaires:
        for question in questions:
            if question in questionnaire:
                count += 1

    return count
Exemple #25
0
def solution():
    instructions = get_input("input.prod")

    aim = 0
    distance = 0
    depth = 0
    for instr in instructions:
        [direction, vector] = instr.split(" ")
        if direction == "forward":
            distance += int(vector)
            depth += aim * int(vector)
        elif direction == "down":
            aim += int(vector)
        else:
            aim -= int(vector)

    return distance * depth
Exemple #26
0
def get_passports():
    input_ = get_input()
    passports = []

    tempstring = ""
    for passport in input_:
        if passport != '':
            tempstring += passport
        else:
            passports.append(tempstring)
            tempstring = ""

    # Add remaining passport if any.
    if tempstring:
        passports.append(tempstring)

    return passports
Exemple #27
0
def sum_masked_values():
    '''
    Read the instructions to assign values to memory addresses, after
    the mask had been applied to those values. Then sum the values in
    the addresses.
    '''
    values = get_input()

    memory = {}

    for val in values:
        if 'mask = ' in val:
            mask = val[7:]
        else:
            match = re.search(r'mem\[(\d+)\] = (\d+)', val)
            memory[int(match.group(1))] = apply_mask(int(match.group(2)), mask)

    return sum(list(memory.values()))
Exemple #28
0
def day_17():
    values = get_input().splitlines()
    cube = []
    grid = []
    for val in values:
        grid.append([c for c in val])
    cube.append(grid)
    for _ in range(6):
        cube = add_layers(cube)
        cube = flip_cubes(cube)

    count = 0
    for x in cube:
        for y in x:
            for z in y:
                if z == '#':
                    count += 1
    return count
Exemple #29
0
def day_16():
    groups = get_input().split('\n\n')

    rules = parse_rules(groups[0])

    my_ticket = [int(n) for n in groups[1].split('\n')[1].split(',')]
    other_tickets = groups[2].split('\n')[1:-1]

    other_tickets = filter_tickets(rules, other_tickets)

    column_map = determine_columns(rules, other_tickets)

    product = 1
    for col, name in column_map.items():
        if 'departure' in name.pop():
            product *= my_ticket[col]

    return product
Exemple #30
0
def solution():
    data = get_input("input.prod")

    hydro_map = {}

    for datum in data:
        [first, second] = datum.split(' -> ')
        [x1, y1] = [int(x) for x in first.split(',')]
        [x2, y2] = [int(x) for x in second.split(',')]

        hydro_map = handle_line(hydro_map, x1, y1, x2, y2)

    count = 0
    for hydro in hydro_map.values():
        if hydro > 1:
            count += 1

    return count