예제 #1
0
                    visited.add(new_candidate)
                    new_candidates.append((new_candidate
                                           if metric == 0
                                           else first_step, new_candidate))

        candidates = new_candidates
        metric += 1

    return None, max_distance + 1


puzzle = (2018, 15)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

initial_map = {}
initial_unit_positions = {}


reading_order = lambda p: p[0][1]*dungeon_width + p[0][0]


infinity = 999999
start_hit_points = 200
initial_attempt = 3
attack_power = {'G': 3, 'E': initial_attempt}
dungeon_width = len(puzzle_input[0])
예제 #2
0
from lib.aoclib import AOCLib

puzzle = (2018, 3)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

cloth = {}
claims = set()
non_viable = set()
oversubscription = 0

for claim in puzzle_input:
    parse = claim.split(' ')
    claim_number = int(parse[0][1:])
    claims.add(claim_number)
    corner = [int(coord) for coord in parse[2][:-1].split(',')]
    size = [int(dimension) for dimension in parse[3].split('x')]
    for y in range(size[1]):
        for x in range(size[0]):
            inch = (corner[0] + x, corner[1] + y)
            claimed_inch = cloth.get(inch, None)
            if not claimed_inch:
                cloth[inch] = [claim_number]
            else:
                if len(claimed_inch) == 1:
                    non_viable.add(claimed_inch[0])
                    oversubscription += 1
예제 #3
0
from lib.aoclib import AOCLib
from lib.pixelgrid import PixelGrid

puzzle = (2017, 21)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

# print(puzzle_input)

pixel_grid = PixelGrid(puzzle_input)

# Puzzle solution parts 1 and 2

iterations = 0

while iterations < 18:
    pixel_grid.expand_grid()
    iterations += 1

    if iterations == 5:
        aoc.print_solution(1, pixel_grid.count_pixels())

aoc.print_solution(2, pixel_grid.count_pixels())
예제 #4
0
from lib.aoclib import AOCLib


def hex_distance(hex_point_1, hex_point_2=(0, 0, 0)):
    return (abs(hex_point_2[0] - hex_point_1[0]) +
            abs(hex_point_2[1] - hex_point_1[1]) +
            abs(hex_point_2[2] - hex_point_1[2])) // 2


puzzle = (2017, 11)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.to_list)

# print(puzzle_input)

# Tri-axis representation (sideways Q*Bert!):
# x-axis = e->w
# y-axis = se->nw
# z-axis = ne->sw
#             _____    y__  _____         _____
#            /     \   |\  /     \       /     \
#      _____/ -2,2,0\____\/ 0,1,-1\_____/ 2,0,-2\_____
#     /     \       /     \       /     \       /     \
#    / -3,2,1\_____/ -1,1,0\_____/ 1,0,-1\_____/3,-1,-2\
#    \       /     \       /     \       /     \       /
예제 #5
0
from lib.aoclib import AOCLib

puzzle = (2018, 21)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

magic_1 = int(puzzle_input[8].split(' ')[1])
magic_2 = int(puzzle_input[12].split(' ')[2])

# I hated this. Really hated it. Not enjoyable in any way shape or form.

part_1 = None
part_2 = None

history = set()

r4 = 0
while part_2 is None:
    r5 = r4 | 0x10000
    r4 = magic_1
    while True:
        r4 = (((r4 + (r5 & 0xff)) & 0xFFFFFF) * magic_2) & 0xFFFFFF
        if r5 < 256:
            if part_1 is None:
                part_1 = r4
                aoc.print_solution(1, part_1)
            else:
예제 #6
0
            if 'part1' not in registers and program_id == 0:
                registers['part1'] = queues[0][0]
            queues[program_id] = queues[program_id][1:]
        else:
            pc_inc = -1
    elif instruction[0] == 'jgz':
        if registers[instruction[1]] > 0:
            pc_inc = (registers[instruction[2]] - 1)

    return pc_inc + 1

puzzle = (2017, 18)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

# print(puzzle_input)

# Puzzle solution parts 1 and 2

program_length = len(puzzle_input)
program = [instruction.split(' ') for instruction in puzzle_input]

registers_0 = Registers({'p': 0})
registers_1 = Registers({'p': 1, 'part2': 0})
program_queues = [[], []]
예제 #7
0
from lib.aoclib import AOCLib

puzzle = (2017, 22)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

# print(puzzle_input)

c = len(puzzle_input) // 2

start_grid = {(x - c, y - c): col
              for y, row in enumerate(puzzle_input)
              for x, col in enumerate(row)}

directions = ((0, -1), (1, 0), (0, 1), (-1, 0))

# Puzzle solution part 1

grid = start_grid.copy()

direction = 0
position = (0, 0)

bursts = 10000
infected = 0
예제 #8
0
        del self._newpots

    def get_extent(self):
        return (min(self._pots) if self._pots else 0,
                max(self._pots) if self._pots else 0)

    def get_pattern(self):
        leftmost = self.get_extent()[0]
        return [pot - leftmost for pot in self._pots]


puzzle = (2018, 12)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

rules = {}

for puzzle_line in puzzle_input[2:]:
    rule = puzzle_line.split(' => ')
    rules[rule[0]] = (rule[1] == '#')

pattern_len = 5

pots = TuringPots()
pots.populate_pots(puzzle_input[0][15:])

generation = 1
예제 #9
0
import math
from lib.aoclib import AOCLib

puzzle = (2017, 3)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1], int)

# print(puzzle_input)

# Puzzle solution part 1:

# Traverse the corners of the spiral...
# Every two turns, increment the number of steps to the
# next corner.

x = 0
y = 0
d = 3
number = 1

steps = 1
increment = True
directions = ((1, 0), (0, 1), (-1, 0), (0, -1))

while number < puzzle_input:
예제 #10
0
def get_factors(n):
    factors = []
    trial = 1
    while (trial * trial) <= n:
        if n % trial == 0:
            factors.append(trial)
            factors.append(n // trial)
        trial += 1
    return factors


puzzle = (2018, 19)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

program = []

for line in puzzle_input[1:]:
    decoded = line.split(' ')
    program.append((decoded[0], tuple(int(v) for v in decoded[1:])))

program_length = len(program)

pc_reg = int(puzzle_input[0].split(' ')[1])

for reg_0_value in (0, 1):
    pc = 0
예제 #11
0
from lib.aoclib import AOCLib

puzzle = (2017, 20)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

# print(puzzle_input)

particle_p = []
particle_v = []
particle_a = []
particle_c = []
particle_d = []

for config in puzzle_input:
    config_elements = config.split(', ')

    particle_p.append(
        [int(coord) for coord in config_elements[0][3:-1].split(',')])
    particle_v.append(
        [int(coord) for coord in config_elements[1][3:-1].split(',')])
    particle_a.append(
        [int(coord) for coord in config_elements[2][3:-1].split(',')])
    particle_c.append(False)
    particle_d.append(None)
예제 #12
0
    circle_size = len(circular_list)

    running_total = 0

    for index in range(circle_size):
        index2 = (index + offset) % circle_size
        if circular_list[index] == circular_list[index2]:
            running_total += circular_list[index]

    return running_total

puzzle = (2017, 1)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input as a list of integers

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.sequence_to_int)

# print(puzzle_input)

# Puzzle solution part 1:

aoc.print_solution(1, solve_puzzle(puzzle_input, 1))

# Puzzle solution part 2

aoc.print_solution(2, solve_puzzle(puzzle_input, len(puzzle_input)//2))
예제 #13
0
from lib.aoclib import AOCLib

puzzle = (2018, 20)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

puzzle_input = aoc.get_puzzle_input(puzzle[1])

empty_room = {'N': None, 'E': None, 'S': None, 'W': None}
directions = {'N': (0, 1), 'E': (1, 0), 'S': (0, -1), 'W': (-1, 0)}
backtrack = {'N': 'S', 'E': 'W', 'S': 'N', 'W': 'E'}

current_position = (0, 0)
maze = {current_position: empty_room.copy()}
index = 1
bracket_stack = []

while True:
    c = puzzle_input[index]
    if c == '$':
        break
    elif c == '|':
        current_position = bracket_stack[-1]
    elif c == ')':
        bracket_stack.pop()
    elif c == '(':
        bracket_stack.append(current_position)
    else:
        new_position = (current_position[0] + directions[c][0],
예제 #14
0
from lib.aoclib import AOCLib

puzzle = (2017, 24)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

components = [tuple(component.split('/')) for component in puzzle_input]

# print(puzzle_input)

# Puzzle solution parts 1 and 2

bridges = [[('0', ), component]
           for component
           in components
           if '0' in component]

strongest_bridge = 0
strongest_longest_bridge = (0, 0)

while bridges:
    bridge = bridges.pop()
    valid_port = (bridge[-1][0]
                  if bridge[-1][1] in bridge[-2]
                  else bridge[-1][1])
예제 #15
0
import re
from lib.aoclib import AOCLib

puzzle = (2017, 7)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1])

# print(puzzle_input)

# Puzzle solution part 1

regex_pattern = r'^([a-z]+) \((\d+)\)(?: -> )?(.*)$'

reg = re.compile(regex_pattern, re.M)

program_info = reg.findall(puzzle_input)

program_table = {}

# Build a table listing all the programs and associated data

for program in program_info:
    program_name = program[0]
    program_weight = int(program[1])
    if program[2] == '':
예제 #16
0
        prev_or_next = 1 if amount > 0 else 2
        for click in range(abs(amount)):
            self.pointer = self.pointer[prev_or_next]

    def pop_tail(self):
        value = self.pointer[0]
        self.pointer[1][2] = self.pointer[2]
        self.pointer = self.pointer[2][1] = self.pointer[1]
        return value


puzzle = (2018, 9)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

puzzle_input = aoc.get_puzzle_input(puzzle[1]).split(' ')

number_of_players = int(puzzle_input[0])
last_marble = int(puzzle_input[6])

scores = [0] * number_of_players

marble_to_play = 1

marbles = FunkyStructure(0)

for puzzle_part in (1, 2):
    while marble_to_play <= last_marble:
        if marble_to_play % 23 == 0:
예제 #17
0
from lib.aoclib import AOCLib

puzzle = (2017, 13)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

# print(puzzle_input)

# puzzle_input = ['0: 3','1: 2', '4: 4', '6: 4']

scanner_range = {}

# Bouncing scanners with range n will catch you iff
# a wrapping scanner with range 2n-2 will catch you.
#
# Condition for being caught at layer L is:
#  'L % R(L) == 0'
#
# where R(L) is the range of the scanner if it wrapped.

for layer in puzzle_input:
    layer_data = layer.split(': ')
    scanner_range[int(layer_data[0])] = int(layer_data[1]) * 2 - 2

number_of_layers = max(scanner_range.keys()) + 1
예제 #18
0
from lib.aoclib import AOCLib
from lib.knothash import KnotHash

puzzle = (2017, 10)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1])

# print(puzzle_input)

awful_hash_1 = KnotHash.get_hash(AOCLib.to_list_int(puzzle_input))

aoc.print_solution(1, awful_hash_1[0][0] * awful_hash_1[0][1])

puzzle_lengths = [ord(character) for character in puzzle_input]
puzzle_lengths.extend([17, 31, 73, 47, 23])

awful_hash_2 = KnotHash.get_hash(puzzle_lengths, rounds=64)

aoc.print_solution(2, awful_hash_2[1])
예제 #19
0
from lib.aoclib import AOCLib

puzzle = (2018, 2)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

repeat_counts = {}

for box_id in puzzle_input:
    letter_counts = {}
    for letter in box_id:
        letter_counts[letter] = letter_counts.get(letter, 0) + 1

    box_letter_runs = {}
    for count in letter_counts.values():
        box_letter_runs[count] = box_letter_runs.get(count, 0) + 1

    for run_length, number in box_letter_runs.items():
        repeat_counts[run_length] = repeat_counts.get(run_length, 0) + 1

aoc.print_solution(1, repeat_counts[2] * repeat_counts[3])

difference_pos = None
correct_box_id = None

for box_number, box_id_1 in enumerate(puzzle_input):
    for box_id_2 in puzzle_input[:box_number]:
예제 #20
0
from lib.aoclib import AOCLib

puzzle = (2017, 9)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1])

# print(puzzle_input)

# Puzzle solution part 1 & 2

# As a by-product, also getting the cleaned stream
# and the positions of all the groups - expected
# part 2 to be more complicated!

inside_garbage = False
garbage_count = 0
skip_next = False
group_positions = []
unclosed_positions = []

clean_stream = ''

score = 0

for i, c in enumerate(puzzle_input):
예제 #21
0
from math import atan2, cos, sin, sqrt
from lib.aoclib import AOCLib

puzzle = (2019, 10)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

asteroids = []

for y, row in enumerate(puzzle_input):
    for x, obj in enumerate(row):
        if obj == '#':
            asteroids.append((x, y))

most_visible = (-1, None)

rounding_factor = -100000
best_asteroid = None

for asteroid in asteroids:
    rays = {}
    for other_asteroid in asteroids:
        if asteroid != other_asteroid:
            x, y = ((other_asteroid[0] - asteroid[0]),
                    (other_asteroid[1] - asteroid[1]))
            direction = round(rounding_factor * atan2(x, y))
            magnitude = sqrt(x * x + y * y)
예제 #22
0
from lib.aoclib import AOCLib

puzzle = (2017, 25)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

# print(puzzle_input)

begin_state = puzzle_input[0][-2]
checksum_steps = int(puzzle_input[1].split()[-2])

state_machine = {}

for state in range(3, len(puzzle_input), 10):
    next_state_0 = (int(puzzle_input[state + 2][-2]),
                    1 if puzzle_input[state + 3][-3] == 'h' else -1,
                    puzzle_input[state + 4][-2])
    next_state_1 = (int(puzzle_input[state + 6][-2]),
                    1 if puzzle_input[state + 7][-3] == 'h' else -1,
                    puzzle_input[state + 8][-2])
    state_machine[puzzle_input[state][-2]] = (next_state_0, next_state_1)

# Puzzle solution

cursor = 0
예제 #23
0
                else:
                    swap_positions = [
                        end_position.index(p) for p in parameter.split('/')
                    ]
                (end_position[swap_positions[0]],
                end_position[swap_positions[1]]) = \
                    (end_position[swap_positions[1]],
                    end_position[swap_positions[0]])
    return end_position


puzzle = (2017, 16)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.to_list)

# print(puzzle_input)

# Puzzle solution part 1

num_programs = 16
start_programs = [chr(97 + c) for c in range(num_programs)]

programs = dance(start_programs, puzzle_input)

aoc.print_solution(1, ''.join(programs))
예제 #24
0
from lib.aoclib import AOCLib

puzzle = (2017, 8)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

# print(puzzle_input)

# Puzzle solution parts 1 & 2
# Rewritten not to use dirty eval()

registers = {}
python_condition = "registers['{0}'] {1} {2}"
max_value = 0

for instruction in puzzle_input:
    parsed_instruction = instruction.split(' ')

    for register_name in [parsed_instruction[0], parsed_instruction[4]]:
        if register_name not in registers:
            registers[register_name] = 0

    cond_reg_val = registers[parsed_instruction[4]]
    cond_num_val = int(parsed_instruction[6])
    cond_oper = parsed_instruction[5]
예제 #25
0
    """Counts the number of 1 bits in 'number'"""

    ones = 0

    while number:
        ones += (number & 1)
        number >>= 1

    return ones


puzzle = (2017, 14)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1])

# print(puzzle_input)

# Puzzle solution part 1

num_cols = 128
num_rows = 128

hash_inputs = ['{}-{}'.format(puzzle_input, row) for row in range(num_rows)]

# Use a cache of part 1's answer as it takes a moderately
예제 #26
0
            pc += 4
        elif opcode == 2:
            a, b, c = program[pc + 1:pc + 4]
            program[c] = program[a] * program[b]
            pc += 4
        elif opcode == 99:
            break

    return program[0]


puzzle = (2019, 2)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.to_list_int)
magic_number = 19690720

part_one = puzzle_input[:]

part_one[1:3] = [12, 2]

part_one_solution = run_program(part_one)

aoc.print_solution(1, part_one_solution)

for noun in range(100):
    for verb in range(100):
        part_two = puzzle_input[:]
예제 #27
0
from lib.aoclib import AOCLib
from intcode_computer import IntcodeComputer

puzzle = (2019, 9)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.to_list_int)

test_mode = IntcodeComputer(puzzle_input, 1).run_to_end()

aoc.print_solution(1, test_mode)

coordinates = IntcodeComputer(puzzle_input, 2).run_to_end()

aoc.print_solution(1, coordinates)
예제 #28
0
from lib.aoclib import AOCLib


def sign(x):
    return -1 if x < 0 else 1 if x > 0 else 0


puzzle = (2019, 12)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

moons = []

for line in puzzle_input:
    moon = ([0, 0, 0], [0, 0, 0])
    coords = line[1:-1].split(', ')
    for coord in coords:
        key, value = coord.split('=')
        axis = 'xyz'.index(key)
        moon[0][axis] = int(value)
    moons.append(moon)

for step in range(1000):
    for moon1 in moons:
        for moon2 in moons:
            if moon1 != moon2:
                for axis in (0, 1, 2):
예제 #29
0
from lib.aoclib import AOCLib
from intcode_computer import IntcodeComputer

puzzle = (2019, 5)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.to_list_int)

diagnostic_code_1 = IntcodeComputer(puzzle_input, 1).run_to_end()

aoc.print_solution(1, diagnostic_code_1)

diagnostic_code_2 = IntcodeComputer(puzzle_input, 5).run_to_end()

aoc.print_solution(2, diagnostic_code_2)
예제 #30
0
from lib.aoclib import AOCLib

puzzle = (2017, 4)

# Initialise the helper library

aoc = AOCLib(puzzle[0])

# Get the puzzle input

puzzle_input = aoc.get_puzzle_input(puzzle[1], AOCLib.lines_to_list)

# print(puzzle_input)

# Puzzle solution part 1

valid_passphrases = 0

for passphrase in puzzle_input:
    words = passphrase.split(' ')
    if len(words) == len(set(words)):
        valid_passphrases += 1

aoc.print_solution(1, valid_passphrases)

# Puzzle solution part 2

valid_passphrases = 0

for passphrase in puzzle_input:
    words = [''.join(sorted(word)) for word in passphrase.split(' ')]