示例#1
0
def puzzle_2(test_input=None):
    def compute_subtree_weights(node):
        node['subtree_weight'] = node['weight']
        for callee in node['callees']:
            node['subtree_weight'] += compute_subtree_weights(stacks[callee])
        return node['subtree_weight']

    def balance_subtree(node, parent_weight=None):
        subtree = node
        target_weight = 0
        weights = [
            stacks[callee]['subtree_weight'] for callee in node['callees']
        ]
        if len(weights) > 1:
            target_weight = weights[0 if weights.count(weights[0]) > 1 else 1]
            for callee in node['callees']:
                if stacks[callee]['subtree_weight'] != target_weight:
                    subtree = stacks[callee]
        if subtree != node:
            return balance_subtree(subtree, target_weight)
        else:
            return parent_weight - len(node['callees']) * target_weight

    stacks = test_input if test_input else aocinput.input_for_day(7)
    root_node = stacks[puzzle_1()]
    compute_subtree_weights(root_node)
    return balance_subtree(root_node)
示例#2
0
def puzzle_2(test_input=None):
    memory_map = test_input if test_input else aocinput.input_for_day(22)
    (y, x) = (0, 0)
    direction = 0
    infection_count = 0
    for _ in range(10000000):
        if y not in memory_map:
            memory_map[y] = {}
        if x not in memory_map[y]:
            memory_map[y][x] = '.'
        if memory_map[y][x] == '.':
            direction = (direction + 3) % 4
            memory_map[y][x] = 'W'
        elif memory_map[y][x] == 'W':
            memory_map[y][x] = '#'
            infection_count += 1
        elif memory_map[y][x] == '#':
            direction = (direction + 1) % 4
            memory_map[y][x] = 'F'
        elif memory_map[y][x] == 'F':
            direction = (direction + 2) % 4
            memory_map[y][x] = '.'
        if direction in [0, 2]:
            y += 1 if direction == 0 else -1
        else:
            x += 1 if direction == 1 else -1
    return infection_count
示例#3
0
def puzzle_1(test_input=None):
    digits = test_input if test_input else aocinput.input_for_day(1)
    solution = int(digits[0]) if digits[0] == digits[len(digits) - 1] else 0
    for i in range(0, len(digits) - 1):
        if digits[i] == digits[i + 1]:
            solution += int(digits[i])
    return solution
示例#4
0
def puzzle_2(test_input=None):
    input = test_input if test_input else aocinput.input_for_day(3)
    mem = {(0, 0): 1}
    position = (0, 0)
    directions = [(1, 0), (0, 1), (-1, 0), (0, -1)]
    direction = directions[0]
    direction_steps_max = 1
    direction_steps = 0
    pivots = 0
    value = 0
    while value < input:
        position = (position[0] + direction[0], position[1] + direction[1])
        direction_steps += 1
        for x in range(position[0] - 1, position[0] + 2):
            for y in range(position[1] - 1, position[1] + 2):
                if (x, y) in mem:
                    value += mem[(x, y)]
        if value < input:
            mem[position] = value
            value = 0
            if direction_steps == direction_steps_max:
                direction = directions[(directions.index(direction) + 1) % 4]
                direction_steps = 0
                pivots += 1
                if pivots % 2 == 0:
                    direction_steps_max += 1
    return value
示例#5
0
def puzzle_2(test_input=None):
    states = test_input if test_input else aocinput.input_for_day(20)
    annihilated_particles = []
    remaining_count = 0
    flatline_count = 0
    while True:
        occupied_positions = {}
        for p in range(len(states)):
            if p not in annihilated_particles:
                pos = states[p][0]
                v = states[p][1]
                a = states[p][2]
                v = (v[0] + a[0], v[1] + a[1], v[2] + a[2])
                pos = (pos[0] + v[0], pos[1] + v[1], pos[2] + v[2])
                if pos in occupied_positions:
                    occupied_positions[pos].append(p)
                else:
                    occupied_positions[pos] = [p]
                    states[p][0] = pos
                    states[p][1] = v
        for position in occupied_positions:
            if len(occupied_positions[position]) > 1:
                for p in occupied_positions[position]:
                    annihilated_particles.append(p)
        if len(states) - len(annihilated_particles) == remaining_count:
            flatline_count += 1
            if flatline_count > 100:
                break
        else:
            remaining_count = len(states) - len(annihilated_particles)
    return remaining_count
示例#6
0
def puzzle_1(test_input=None):
    def bridge_strength(bridge):
        strength = 0
        for component in bridge:
            strength += component[0] + component[1]
        return strength

    def continue_bridge(bridge, required_pin):
        sub_bridges = []
        for component in components:
            if component not in bridge and required_pin in component:
                next_pin = component[1 if component[0] == required_pin else 0]
                sub_bridges.append(continue_bridge(bridge + [component], next_pin))
        if len(sub_bridges) == 0:
            return bridge
        max_strength = 0
        strongest_bridge = []
        for sub_bridge in sub_bridges:
            strength = bridge_strength(sub_bridge)
            if strength > max_strength:
                max_strength = strength
                strongest_bridge = sub_bridge
        return strongest_bridge

    components = test_input if test_input else aocinput.input_for_day(24)
    return bridge_strength(continue_bridge([], 0))
示例#7
0
def puzzle_2(test_input=None):
    links = test_input if test_input else aocinput.input_for_day(12)
    grouped_programs = []
    key_programs = []
    num_groups = -1
    group_size = -1
    group = set([])
    while len(key_programs) > num_groups:
        num_groups = len(key_programs)
        for program in links.keys():
            if len(group) == 0 and program not in grouped_programs:
                group.add(program)
                grouped_programs.append(program)
                key_programs.append(program)
        while len(group) > group_size:
            group_size = len(group)
            for program in links.keys():
                if program not in group:
                    for linked_program in links[program]:
                        if linked_program in group:
                            group.add(program)
                            grouped_programs.append(program)
        group_size = -1
        group = set([])
    return len(key_programs)
示例#8
0
def puzzle_1(test_input=None):
    steps = test_input if test_input else aocinput.input_for_day(11)
    position = (0.0, 0.0)
    deltas = hexagonal_deltas()
    for step in steps:
        position = (position[0] + deltas[step][0], position[1] + deltas[step][1])
    return compute_distance(position)
示例#9
0
def puzzle_1(test_input=None):
    key = test_input if test_input else aocinput.input_for_day(14)
    used_blocks = 0
    for i in range(0, 128):
        row = day10.puzzle_2("%s-%d" % (key, i))
        used_blocks += bin(int(row, 16))[2:].count('1')
    return used_blocks
示例#10
0
def puzzle_2(test_input=None):
    def int_or_register(value):
        try:
            return int(value)
        except ValueError:
            return registers[program][value]

    instructions = test_input if test_input else aocinput.input_for_day(18)
    registers = {0: {'p': 0}, 1: {'p': 1}}
    queue = [[], []]
    state = [1, 1]  # 1: running; 0: waiting; -1: terminated
    step = [0, 0]
    program = 0
    snd_count = [0, 0]
    while True:
        instruction = instructions[step[program]]
        elements = instruction.split(' ')
        operator = elements[0]
        register = elements[1]
        if register not in registers[program]:
            registers[program][register] = 0
        value = int_or_register(elements[2]) if len(elements) > 2 else None
        did_jump = False
        did_swap = False
        if operator == 'snd':
            queue[1 - program].append(registers[program][register])
            snd_count[program] += 1
        elif operator == 'set':
            registers[program][register] = value
        elif operator == 'add':
            registers[program][register] += value
        elif operator == 'mul':
            registers[program][register] *= value
        elif operator == 'mod':
            registers[program][register] %= value
        elif operator == 'rcv':
            if len(queue[program]) > 0:
                registers[program][register] = queue[program].pop(0)
                state[program] = 1
            else:
                if state[1 - program] == -1:
                    break
                if state[1 - program] == 0 and len(queue[1 - program]) == 0:
                    break
                state[program] = 0
                program = 1 - program
                did_swap = True
        elif operator == 'jgz':
            if int_or_register(register) > 0:
                step[program] += value
                did_jump = True
        if not did_jump and not did_swap:
            step[program] += 1
        if step[program] not in range(0, len(instructions)):
            if state[1 - program] == -1:
                break
            state[program] = -1
            program = 1 - program
    return snd_count[1]
示例#11
0
def puzzle_2(test_input=None):
    digits = test_input if test_input else aocinput.input_for_day(1)
    count = len(digits)
    solution = 0
    for i in range(0, len(digits)):
        if digits[i] == digits[(i + count / 2) % count]:
            solution += int(digits[i])
    return solution
示例#12
0
def puzzle_1(test_input=None):
    stacks = test_input if test_input else aocinput.input_for_day(7)
    callees = set()
    for program in stacks:
        stack = stacks[program]
        for callee in stack['callees']:
            if callee in stacks:
                callees.add(callee)
    return list(set(stacks.keys()).difference(callees))[0]
示例#13
0
def puzzle_2():
    rows = aocinput.input_for_day(2)
    even_division_sum = 0
    for row in rows:
        for dividend in row:
            for divisor in row:
                if dividend != divisor and dividend % divisor == 0:
                    even_division_sum += dividend / divisor
    return even_division_sum
示例#14
0
def puzzle_1(test_input=None):
    scan_ranges = test_input if test_input else aocinput.input_for_day(13)
    penalty = 0
    for depth in scan_ranges.keys():
        scan_range = scan_ranges[depth]
        if depth % (scan_range - 1) == 0 and (depth /
                                              (scan_range - 1)) % 2 == 0:
            penalty += depth * scan_range
    return penalty
示例#15
0
def puzzle_1(test_input=None):
    states = test_input if test_input else aocinput.input_for_day(20)
    min_a = 100000000
    min_p = 0
    for p in range(len(states)):
        a = abs(states[p][2][0]) + abs(states[p][2][1]) + abs(states[p][2][2])
        if a < min_a:
            min_a = a
            min_p = p
    return min_p
示例#16
0
def puzzle_1(test_input=None, iterations=40000000):
    generator_inputs = test_input if test_input else aocinput.input_for_day(15)
    result_1 = generator_inputs[0]
    result_2 = generator_inputs[1]
    match_count = 0
    for _ in xrange(0, iterations):
        result_1 = (result_1 * 16807) % 2147483647
        result_2 = (result_2 * 48271) % 2147483647
        if result_1 & 65535 == result_2 & 65535:
            match_count += 1
    return match_count
示例#17
0
def puzzle_1(test_input=None):
    steps = test_input if test_input else aocinput.input_for_day(17)
    position = 0
    spinlock = [position]
    value = 1
    while value < 2018:
        position = (position + (steps % value)) % value
        spinlock.insert(position + 1, value)
        position += 1
        value += 1
    return spinlock[position + 1]
示例#18
0
def puzzle_2(test_input=None):
    steps = test_input if test_input else aocinput.input_for_day(17)
    position = 0
    value = 1
    value_at_1 = 0
    while value < 50000000:
        position = (position + steps) % value
        if position == 0:
            value_at_1 = value
        position += 1
        value += 1
    return value_at_1
示例#19
0
def puzzle_1(test_input=None):
    links = test_input if test_input else aocinput.input_for_day(12)
    group_with_0 = set('0')
    group_size = 0
    iterations = 0
    while len(group_with_0) > group_size:
        group_size = len(group_with_0)
        for program in links.keys():
            if program not in group_with_0:
                for linked_program in links[program]:
                    iterations += 1
                    if linked_program in group_with_0:
                        group_with_0.add(program)
    return len(group_with_0)
示例#20
0
def puzzle_2(test_input=None):
    scan_ranges = test_input if test_input else aocinput.input_for_day(13)
    delay = 0
    collisions = 1
    while collisions > 0:
        collisions = 0
        delay += 1
        for depth in scan_ranges.keys():
            scan_range = scan_ranges[depth]
            if (depth + delay) % (scan_range - 1) == 0 and (
                (depth + delay) / (scan_range - 1)) % 2 == 0:
                collisions += 1
                break
    return delay
示例#21
0
def puzzle_1(test_input=None):
    input = test_input if test_input else aocinput.input_for_day(3)
    quadrant_value = 3
    quadrant_size = 2
    pivots = 0
    while quadrant_value < input:
        quadrant_value += quadrant_size
        pivots += 1
        if quadrant_value < input and pivots % 2 == 0:
            quadrant_size += 1
    manhattan_distance = 2 * (pivots / 4 + 1) - (quadrant_value - input)
    if pivots % 4 == 3:
        manhattan_distance += 1
    return manhattan_distance
示例#22
0
def puzzle_2(test_input=None):
    input = test_input if test_input else aocinput.input_for_day(10, 2)
    lengths = map(lambda character: ord(character), input)
    lengths += [17, 31, 73, 47, 23]
    sparse_hash = compute_sparse_hash(lengths, 64)
    dense_hash = []
    xor_result = 0
    for i in range(256):
        if i > 0 and i % 16 == 0:
            dense_hash.append(xor_result)
            xor_result = 0
        xor_result ^= sparse_hash[i]
    dense_hash.append(xor_result)
    knot_hash = ''
    for hash_element in dense_hash:
        knot_hash += format(hash_element, '02x')
    return knot_hash
示例#23
0
def puzzle_1(test_input=None):
    def int_or_register(value):
        try:
            return int(value)
        except ValueError:
            return registers[value]

    instructions = test_input if test_input else aocinput.input_for_day(18)
    registers = {}
    last_sound_played = None
    step = 0
    while step in range(0, len(instructions)):
        instruction = instructions[step]
        elements = instruction.split(' ')
        operator = elements[0]
        register = elements[1]
        if register not in registers:
            registers[register] = 0
        value = int_or_register(elements[2]) if len(elements) > 2 else None
        did_jump = False
        if operator == 'snd':
            last_sound_played = registers[register]
        elif operator == 'set':
            registers[register] = value
        elif operator == 'add':
            registers[register] += value
        elif operator == 'mul':
            registers[register] *= value
        elif operator == 'mod':
            registers[register] %= value
        elif operator == 'rcv':
            if registers[register] > 0:
                return last_sound_played
        elif operator == 'jgz':
            if registers[register] > 0:
                step += value
                did_jump = True
        if not did_jump:
            step += 1
示例#24
0
def puzzle_2(test_input=None, max_comparisons=5000000):
    generator_inputs = test_input if test_input else aocinput.input_for_day(15)
    result_1 = generator_inputs[0]
    result_2 = generator_inputs[1]
    offset_1 = 0
    offset_2 = 0
    comparisons = 0
    match_count = 0
    while comparisons < max_comparisons:
        if offset_1 <= comparisons:
            result_1 = (result_1 * 16807) % 2147483647
            if result_1 % 4 == 0:
                offset_1 += 1
        if offset_2 <= comparisons:
            result_2 = (result_2 * 48271) % 2147483647
            if result_2 % 8 == 0:
                offset_2 += 1
        if offset_1 > comparisons and offset_2 > comparisons:
            if result_1 & 65535 == result_2 & 65535:
                match_count += 1
            comparisons += 1
    return match_count
示例#25
0
def puzzle_2(test_input=None):
    def merge_regions(result_region, redundant_region):
        for (row, column) in regions[redundant_region]:
            regions[result_region].append((row, column))
            region_map[(row, column)] = result_region
        regions.pop(redundant_region)
        return result_region

    key = test_input if test_input else aocinput.input_for_day(14)
    rows = []
    region_map = {}
    current_region = None
    encountered_regions = 0
    regions = {}
    for i in range(0, 128):
        row = bin(int(day10.puzzle_2("%s-%d" % (key, i)), 16))[2:]
        rows.append(("%128s" % row).replace(' ', '0'))
    for i in range(0, 128):
        for j in range(0, 128):
            if rows[i][j] == '0':
                region_map[(i, j)] = 0
                current_region = None
            else:
                region_above = region_map[(i - 1, j)] if i > 0 else None
                if not current_region and rows[i][j] == '1':
                    if region_above:
                        current_region = region_above
                    else:
                        encountered_regions += 1
                        current_region = encountered_regions
                        regions[current_region] = []
                else:
                    if region_above and region_above != current_region:
                        current_region = merge_regions(region_above,
                                                       current_region)
                region_map[(i, j)] = current_region
                regions[current_region].append((i, j))
        current_region = None
    return len(regions)
示例#26
0
def puzzle_1(test_input=None):
    def int_or_register(value):
        try:
            return int(value)
        except ValueError:
            return registers[value]

    instructions = test_input if test_input else aocinput.input_for_day(23)
    registers = {}
    step = 0
    mul_count = 0
    while True:
        instruction = instructions[step]
        elements = instruction.split(' ')
        operator = elements[0]
        register = elements[1]
        if register not in registers:
            registers[register] = 0
        value = int_or_register(elements[2]) if len(elements) > 2 else None
        did_jump = False
        if operator == 'set':
            registers[register] = value
        elif operator == 'sub':
            registers[register] -= value
        elif operator == 'mul':
            registers[register] *= value
            mul_count += 1
        elif operator == 'mod':
            registers[register] %= value
        elif operator == 'jnz':
            if int_or_register(register) != 0:
                step += value
                did_jump = True
        if not did_jump:
            step += 1
        if step not in range(0, len(instructions)):
            break
    return mul_count
示例#27
0
def puzzle_1(test_input=None, start_state=None):
    moves = test_input if test_input else aocinput.input_for_day(16)
    programs = list(start_state) if start_state else list('abcdefghijklmnop')
    for move in moves:
        move_type = move[0]
        instruction = move[1:]
        if move_type == 's':
            tail = programs[-int(instruction):]
            head = programs[:16 - int(instruction)]
            programs = tail + head
        elif move_type == 'x':
            (a, b) = instruction.split('/')
            program_a = programs[int(a)]
            program_b = programs[int(b)]
            programs[int(a)] = program_b
            programs[int(b)] = program_a
        else:
            (program_a, program_b) = instruction.split('/')
            index_a = programs.index(program_a)
            index_b = programs.index(program_b)
            programs[index_a] = program_b
            programs[index_b] = program_a
    return ''.join(programs)
示例#28
0
def puzzle_1_recursive(test_input=None):
    def linked_to_0(program):
        if program in group_0:
            return True
        else:
            linked = False
            for linked_program in links[program]:
                puzzle_1_recursive.iterations += 1
                if linked_program not in visiting:
                    visiting.add(linked_program)
                    linked = linked or linked_to_0(linked_program)
                    visiting.remove(linked_program)
            if linked:
                group_0.add(program)
            return linked

    links = test_input if test_input else aocinput.input_for_day(12)
    group_0 = set('0')
    visiting = set()
    puzzle_1_recursive.iterations = 0
    for program in links.keys():
        linked_to_0(program)
    print("Iterations: %d" % puzzle_1_recursive.iterations)
    return len(group_0)
示例#29
0
def puzzle_2(test_input=None):
    rules = test_input if test_input else aocinput.input_for_day(21)
    return day21_shared(rules, 2)
示例#30
0
def puzzle_2(test_input=None):
    passphrases = test_input if test_input else aocinput.input_for_day(4)
    return day04_shared(passphrases, 2)