コード例 #1
0
ファイル: day12.py プロジェクト: nairarunraj/advent_of_code
def puzzle1(input_file) -> int:
    input_content = get_input_data(input_file)

    x_pos = 0
    y_pos = 0
    direction = 0
    direction_x = (1, 0, -1, 0)
    direction_y = (0, -1, 0, 1)
    for instr in input_content:
        (cmd, value) = (instr[0], int(instr[1:]))

        if cmd == 'F':
            x_pos += (value * direction_x[direction])
            y_pos += (value * direction_y[direction])

        elif cmd == 'R':
            direction = (direction + int(value / 90)) % 4

        elif cmd == 'L':
            direction = (direction + int(value / 90) * 3) % 4

        elif cmd == 'N':
            y_pos += value

        elif cmd == 'S':
            y_pos -= value

        elif cmd == 'E':
            x_pos += value

        elif cmd == 'W':
            x_pos -= value

    return abs(x_pos) + abs(y_pos)
コード例 #2
0
ファイル: day7.py プロジェクト: nairarunraj/advent_of_code
def puzzle1(input_file) -> int:
    input_content = get_input_data(input_file)
    color_rules, bag_contain_rules = get_rules(input_content)

    shiny_gold_bags = []
    visited = {}
    for bag in bag_contain_rules['shiny gold'].keys():
        visited[bag] = 1
        shiny_gold_bags.append(bag)

    current_index = 0
    while True:
        if current_index == len(shiny_gold_bags):
            break

        current_color = shiny_gold_bags[current_index]
        if current_color not in bag_contain_rules:
            current_index += 1
            continue

        for bag in bag_contain_rules[current_color].keys():

            if bag == 'shiny gold':
                current_index += 1
                continue
            if bag not in visited:
                shiny_gold_bags.append(bag)
                visited[bag] = 1

        current_index += 1

    return len(shiny_gold_bags)
コード例 #3
0
ファイル: day17.py プロジェクト: nairarunraj/advent_of_code
def puzzle2(input_file) -> int:
    input_content = get_input_data(input_file)

    neighbors = [
        coord for coord in itertools.product([-1, 0, 1], repeat=4)
        if coord != (0, 0, 0, 0)
    ]

    grid4d = set()

    for y, line in enumerate(input_content):
        for x, ch in enumerate(line):
            if ch == '#':
                grid4d.add((x, y, 0, 0))

    for _ in range(6):
        grid4d_copy = set()
        range_x = get_range(0, grid4d)
        range_y = get_range(1, grid4d)
        range_z = get_range(2, grid4d)
        range_w = get_range(3, grid4d)
        for coord in itertools.product(range_x, range_y, range_z, range_w):
            if coord in grid4d:
                if nbs4(neighbors, grid4d, coord) in (2, 3):
                    grid4d_copy.add(coord)
            else:
                if nbs4(neighbors, grid4d, coord) == 3:
                    grid4d_copy.add(coord)
        grid4d = grid4d_copy

    return len(grid4d)
コード例 #4
0
def puzzle1(input_file) -> int:
    input_content = get_input_data(input_file)

    mask = {}
    memory = {}
    for line in input_content:
        if line.startswith("mask"):
            mask = {}
            (_, mask_val) = line.split(" = ")
            for idx, mask_bit in enumerate(reversed(mask_val)):
                if mask_bit != 'X':
                    mask[int(idx)] = int(mask_bit)

            continue

        (mem, val_str) = line.split(" = ")
        mem_val = int(mem[4:-1])
        val = int(val_str)
        result_val = val
        for idx, mask_bit in sorted(mask.items()):
            result_val = modify_bit(result_val, idx, mask_bit)

        memory[mem_val] = result_val

    return sum(memory.values())
コード例 #5
0
ファイル: day25.py プロジェクト: nairarunraj/advent_of_code
def puzzle1(input_file) -> int:
    input_content = get_input_data(input_file)

    card_pub_key = int(input_content[0])
    door_pub_key = int(input_content[1])

    loop_sizes = {}
    subject_no = 7
    loop_size = 0
    public_key = 1
    while True:
        if len(loop_sizes) == 2:
            break

        if public_key == card_pub_key:
            loop_sizes['card'] = loop_size

        if public_key == door_pub_key:
            loop_sizes['door'] = loop_size

        public_key *= subject_no
        public_key %= 20201227

        loop_size += 1

    subject_no = door_pub_key
    public_key = 1
    for _ in range(loop_sizes['card']):
        public_key *= subject_no
        public_key %= 20201227

    return public_key
コード例 #6
0
ファイル: day21.py プロジェクト: nairarunraj/advent_of_code
def puzzle1(input_file) -> int:
    input_content = get_input_data(input_file)

    foods = []
    for line in input_content:
        (ingredients, allergens) = line.split(' (contains ')
        ing = set(ingredients.split(' '))

        aller = set(allergens[:-1].split(', '))
        foods.append((ing, aller))

    all_ing = set()
    all_allerg = set()
    for ing, aller in foods:
        all_ing |= ing
        all_allerg |= aller

    possible_allergic_ing = {ing: set(all_allerg) for ing in all_ing}

    count_ings = defaultdict(int)
    for ings, allergs in foods:
        for ing in ings:
            count_ings[ing] += 1

        for allerg in allergs:
            for ing in all_ing:
                if ing not in ings:
                    possible_allergic_ing[ing].discard(allerg)

    count = 0
    for ing in all_ing:
        if not possible_allergic_ing[ing]:
            count += count_ings[ing]

    return count
コード例 #7
0
ファイル: day22.py プロジェクト: nairarunraj/advent_of_code
def puzzle1(input_file) -> int:
    input_content = get_input_data(input_file)

    player = player1 = []
    for line in input_content:
        if 'Player' in line:
            continue

        if line == '':
            player1 = copy.deepcopy(player)
            player = []
            continue

        player.append(int(line))

    player2 = player

    while len(player1) != 0 and len(player2) != 0:
        card1 = player1.pop(0)
        card2 = player2.pop(0)
        if card1 > card2:
            player1.append(card1)
            player1.append(card2)
        else:
            player2.append(card2)
            player2.append(card1)

    if len(player1) == 0:
        player = player2
    else:
        player = player1

    return sum([i * card for i, card in enumerate(reversed(player), 1)])
コード例 #8
0
ファイル: day8.py プロジェクト: nairarunraj/advent_of_code
def puzzle1(input_file) -> int:
    input_content = get_input_data(input_file)

    current_index = 0
    visited = {}
    accumulator = 0
    while True:
        if current_index == len(input_content):
            return accumulator

        if current_index in visited:
            return accumulator

        instruction = input_content[current_index]
        (op, offset) = instruction.split(' ')
        direction = offset[0]
        offset_val = int(offset[1:])

        visited[current_index] = 1

        multiplier = 1
        if direction == '-': multiplier = -1

        if op == 'acc': accumulator += (multiplier * offset_val)

        if op in ('nop', 'acc'):
            current_index += 1
            continue

        if op == 'jmp':
            current_index += (multiplier * offset_val)

    return accumulator
コード例 #9
0
ファイル: day22.py プロジェクト: nairarunraj/advent_of_code
def puzzle2(input_file) -> int:
    input_content = get_input_data(input_file)

    player = player1 = []
    for line in input_content:
        if 'Player' in line:
            continue

        if line == '':
            player1 = copy.deepcopy(player)
            player = []
            continue

        player.append(int(line))

    player2 = player

    winner = play_game(player1, player2)

    if winner == 1:
        player = player1
    else:
        player = player2

    return sum([i * card for i, card in enumerate(reversed(player), 1)])
コード例 #10
0
ファイル: day7.py プロジェクト: nairarunraj/advent_of_code
def puzzle2(input_file) -> int:
    input_content = get_input_data(input_file)

    color_rules, bag_contain_rules = get_rules(input_content)

    total_count = get_internal_bags(color_rules, 'shiny gold')

    return total_count
コード例 #11
0
def puzzle2(input_file) -> int:
    input_content = get_input_data(input_file)

    ticket_rules = {}
    your = False
    nearby = False
    your_tickets = []
    nearby_tickets = []
    for line in input_content:
        if line == '': continue

        if line == 'your ticket:':
            your = True
            continue

        if line == 'nearby tickets:':
            nearby = True
            continue

        if not your and not nearby:
            rule = line.split(":")
            ranges = rule[1].lstrip().split(' or ')
            ticket_rules[rule[0]] = [[int(limit) for limit in vals.split('-')]
                                     for vals in ranges]
            continue

        if your and not nearby:
            your_tickets = [int(ticket) for ticket in line.split(',')]
            continue

        if nearby:
            nearby_tickets.append([int(ticket) for ticket in line.split(',')])

    valid_tickets = []
    for ticket_row in nearby_tickets:
        valid_ticket_row = True
        for ticket in ticket_row:
            valid_ticket = False
            for rules in ticket_rules.values():
                if rules[0][0] <= ticket <= rules[0][1] or rules[1][
                        0] <= ticket <= rules[1][1]:
                    valid_ticket = True
            if not valid_ticket:
                valid_ticket_row = False
                break

        if valid_ticket_row:
            valid_tickets.append(ticket_row)

    no_of_rules = len(your_tickets)
    final_cols = get_row_index(no_of_rules, {}, ticket_rules, valid_tickets)

    product = 1
    for index, name in final_cols.items():
        if name.startswith('departure '):
            product *= your_tickets[index]

    return product
コード例 #12
0
ファイル: day3.py プロジェクト: nairarunraj/advent_of_code
def puzzle2(input_file) -> int:
    slopes = ((1, 1), (3, 1), (5, 1), (7, 1), (1, 2))

    input_content = get_input_data(input_file)

    product = 1
    for (slope_x, slope_y) in slopes:
        product *= get_tree_count_for_slope(input_content, slope_x, slope_y)

    return product
コード例 #13
0
ファイル: day5.py プロジェクト: nairarunraj/advent_of_code
def puzzle1(input_file) -> int:
    input_content = get_input_data(input_file)

    max_seat_id = 0

    for seat_code in input_content:
        seat_id = get_seat_id(seat_code)
        if seat_id > max_seat_id: max_seat_id = seat_id

    return max_seat_id
コード例 #14
0
ファイル: day19.py プロジェクト: nairarunraj/advent_of_code
def puzzle1(input_file) -> int:
    input_content = get_input_data(input_file)

    (rules, strings_to_check) = parse_input(input_content)

    valid_strings = 0
    for line in strings_to_check:
        if len(line) in is_line_valid(rules, '0', line, 0):
            valid_strings += 1

    return valid_strings
コード例 #15
0
def puzzle2(input_file) -> int:
    input_content = get_input_data(input_file)
    valid_passwords = 0
    for policy in input_content:
        (char_restriction, character, password) = policy.split(" ")
        character = character.rstrip(":")

        (first_index, second_index) = [int(number) - 1 for number in char_restriction.split('-')]

        if bool(password[first_index] == character) != bool(password[second_index] == character):
            valid_passwords += 1

    return valid_passwords
コード例 #16
0
ファイル: day19.py プロジェクト: nairarunraj/advent_of_code
def puzzle2(input_file) -> int:
    input_content = get_input_data(input_file)

    (rules, strings_to_check) = parse_input(input_content)

    rules['8'] = [['42'], ['42', '8']]
    rules['11'] = [['42', '31'], ['42', '11', '31']]

    valid_strings = 0
    for line in strings_to_check:
        if len(line) in is_line_valid(rules, '0', line, 0):
            valid_strings += 1

    return valid_strings
コード例 #17
0
ファイル: day21.py プロジェクト: nairarunraj/advent_of_code
def puzzle2(input_file) -> int:
    input_content = get_input_data(input_file)

    foods = []
    for line in input_content:
        (ingredients, allergens) = line.split(' (contains ')
        ing = set(ingredients.split(' '))

        aller = set(allergens[:-1].split(', '))
        foods.append((ing, aller))

    all_ing = set()
    all_allerg = set()
    for ing, aller in foods:
        all_ing |= ing
        all_allerg |= aller

    possible_allergic_ing = {ing: set(all_allerg) for ing in all_ing}

    for ings, allergs in foods:
        for allerg in allergs:
            for ing in all_ing:
                if ing not in ings:
                    possible_allergic_ing[ing].discard(allerg)

    fixed_allergic_ing = {}
    while len(fixed_allergic_ing) < len(all_allerg):
        new_possible_allergic_ing = possible_allergic_ing
        for ing, allergs in possible_allergic_ing.items():
            if len(allergs) == 1:
                for allerg in allergs:
                    fixed_allergic_ing[allerg] = ing

                continue

            new_allergs = set()
            for allerg in allergs:
                if allerg not in fixed_allergic_ing:
                    new_allergs.add(allerg)

            new_possible_allergic_ing[ing] = new_allergs

        possible_allergic_ing = new_possible_allergic_ing

    ing_list = [
        fixed_allergic_ing[allerg] for allerg in sorted(fixed_allergic_ing)
    ]

    return ','.join(ing_list)
コード例 #18
0
ファイル: day18.py プロジェクト: nairarunraj/advent_of_code
def puzzle1(input_file) -> int:
    input_content = get_input_data(input_file)

    sum_expr = 0
    for line in input_content:
        line = line.replace("(", " ( ")
        line = line.replace(")", " ) ")
        exprs = line.split(' ')
        operands = []
        operators = []
        for expr in exprs:
            if expr == '':
                continue
            if expr in ('+', '*'):
                if len(operators) > 0 and operators[-1] in ('+', '*'):
                    operator = operators.pop()
                    operand1 = operands.pop()
                    operand2 = operands.pop()
                    if operator == '+':
                        operands.append(operand1 + operand2)
                    if operator == '*':
                        operands.append(operand1 * operand2)
                operators.append(expr)
                continue

            if expr == '(':
                operators.append('(')
                continue

            if expr == ')':
                while (operator := operators.pop()) != '(':
                    operand1 = operands.pop()
                    operand2 = operands.pop()
                    if operator == '+':
                        operands.append(operand1 + operand2)
                    if operator == '*':
                        operands.append(operand1 * operand2)

                continue

            operands.append(int(expr))

        while len(operators) > 0 and (operator := operators.pop()) != '(':
            operand1 = operands.pop()
            operand2 = operands.pop()
            if operator == '+':
                operands.append(operand1 + operand2)
            if operator == '*':
                operands.append(operand1 * operand2)
コード例 #19
0
def puzzle1(input_file) -> int:
    input_content = get_input_data(input_file)
    time_start = int(input_content[0])
    bus_ids = [int(id) for id in input_content[1].split(',') if id.isdigit()]

    min_wait_time = math.inf
    bus_to_catch = 0
    for bus_id in bus_ids:
        wait_time = (-1 * time_start) % bus_id

        if min_wait_time > wait_time:
            min_wait_time = wait_time
            bus_to_catch = bus_id

    return min_wait_time * bus_to_catch
コード例 #20
0
ファイル: day5.py プロジェクト: nairarunraj/advent_of_code
def puzzle2(input_file) -> int:
    input_content = get_input_data(input_file)

    seat_map = [0 for _ in range(1024)]

    for seat_code in input_content:
        seat_id = get_seat_id(seat_code)
        seat_map[seat_id] = 1

    first_occupant_found = False
    for seat_id in range(1024):
        if first_occupant_found and seat_map[seat_id] == 0:
            return seat_id

        if seat_map[seat_id] == 1:
            first_occupant_found = True

    return 0
コード例 #21
0
def puzzle1(input_file) -> int:
    input_content = get_input_data(input_file)
    valid_passwords = 0
    for policy in input_content:
        (char_restriction, character, password) = policy.split(" ")
        character = character.rstrip(":")

        char_count = 0
        for pass_char in password:
            if pass_char == character:
                char_count += 1

        (min_chars, max_chars) = [int(number) for number in char_restriction.split('-')]

        if min_chars <= char_count <= max_chars:
            valid_passwords += 1

    return valid_passwords
コード例 #22
0
def puzzle1(input_file) -> int:
    input_content = get_input_data(input_file)

    ticket_rules = {}
    your = False
    nearby = False
    nearby_tickets = []
    for line in input_content:
        if line == '': continue

        if line == 'your ticket:':
            your = True
            continue

        if line == 'nearby tickets:':
            nearby = True
            continue

        if not your and not nearby:
            rule = line.split(":")
            ranges = rule[1].lstrip().split(' or ')
            ticket_rules[rule[0]] = [[int(limit) for limit in vals.split('-')]
                                     for vals in ranges]
            continue

        if nearby:
            nearby_tickets.append([int(ticket) for ticket in line.split(',')])

    invalid_tickets = []
    for ticket_row in nearby_tickets:
        for ticket in ticket_row:
            valid_ticket = False
            for rules in ticket_rules.values():
                if rules[0][0] <= ticket <= rules[0][1] or rules[1][
                        0] <= ticket <= rules[1][1]:
                    valid_ticket = True
                    break
            if not valid_ticket:
                invalid_tickets.append(ticket)

    return sum(invalid_tickets)
コード例 #23
0
ファイル: day24.py プロジェクト: nairarunraj/advent_of_code
def puzzle1(input_file) -> int:
    input_content = get_input_data(input_file)

    tiles = set()
    start_tile = (0, 0)
    dir_map = {
        'nw': (0.5, 0.5),
        'ne': (-0.5, 0.5),
        'sw': (0.5, -0.5),
        'se': (-0.5, -0.5),
        'e': (-1, 0),
        'w': (1, 0)
    }

    for line in input_content:
        path = []
        prev = ''
        for ch in line:
            if prev in ('n', 's'):
                direction = prev + ch
                prev = ''
                path.append(direction)
                continue

            if ch in ('n', 's'):
                prev = ch
                continue

            path.append(ch)

        current_tile = start_tile
        for nav in path:
            current_tile = get_dir(dir_map, nav, current_tile)

        if current_tile in tiles:
            tiles.remove(current_tile)
        else:
            tiles.add(current_tile)

    return len(tiles)
コード例 #24
0
def puzzle2(input_file) -> int:
    input_content = get_input_data(input_file)

    bus_ids = [
        'x' if bus_id == 'x' else int(bus_id)
        for bus_id in input_content[1].split(',')
    ]

    buses = {
        bus_id: -idx % bus_id
        for idx, bus_id in enumerate(bus_ids) if bus_id != 'x'
    }

    sorted_ids = list(reversed(sorted(buses)))
    timestamp = buses[sorted_ids[0]]
    multiplier = sorted_ids[0]
    for bus_id in sorted_ids[1:]:
        while timestamp % bus_id != buses[bus_id]:
            timestamp += multiplier

        multiplier *= bus_id

    return timestamp
コード例 #25
0
def puzzle2(input_file) -> int:
    input_content = get_input_data(input_file)

    mask = {}
    mask_x = {}
    memory = {}
    for line in input_content:
        if line.startswith("mask"):
            mask = {}
            mask_x = []
            (_, mask_val) = line.split(" = ")
            for idx, mask_bit in enumerate(reversed(mask_val)):
                if mask_bit == 'X':
                    mask_x.append(int(idx))
                    continue

                mask[int(idx)] = int(mask_bit)

            continue

        (mem, val_str) = line.split(" = ")
        mem_val = int(mem[4:-1])
        val = int(val_str)

        result_addr = mem_val
        for idx, mask_bit in sorted(mask.items()):
            if mask_bit == 0:
                continue
            result_addr = modify_bit(result_addr, idx, mask_bit)

        addresses = {result_addr}
        addresses = modify_floating_bit(result_addr, mask_x, addresses, 0)
        for addr in addresses:
            memory[addr] = val

    return sum(memory.values())
コード例 #26
0
ファイル: day3.py プロジェクト: nairarunraj/advent_of_code
def puzzle1(input_file) -> int:
    input_content = get_input_data(input_file)

    return get_tree_count_for_slope(input_content, 3, 1)
コード例 #27
0
ファイル: day12.py プロジェクト: nairarunraj/advent_of_code
def puzzle2(input_file) -> int:
    input_content = get_input_data(input_file)

    x_pos = 0
    y_pos = 0
    waypoint_rel_x = waypoint_x = 10
    waypoint_rel_y = waypoint_y = 1
    for instr in input_content:
        (cmd, value) = (instr[0], int(instr[1:]))

        if cmd == 'F':
            ship_x = waypoint_rel_x * value
            ship_y = waypoint_rel_y * value
            x_pos += ship_x
            y_pos -= ship_y

            waypoint_x = x_pos + waypoint_rel_x
            waypoint_y = x_pos + waypoint_rel_y

        if cmd == 'R':
            if value == 90:
                waypoint_x = x_pos + waypoint_rel_y
                waypoint_y = y_pos - waypoint_rel_x

            if value == 180:
                waypoint_x = x_pos - waypoint_rel_x
                waypoint_y = y_pos - waypoint_rel_y

            if value == 270:
                waypoint_x = x_pos - waypoint_rel_y
                waypoint_y = y_pos + waypoint_rel_x

            waypoint_rel_x = waypoint_x - x_pos
            waypoint_rel_y = waypoint_y - y_pos

        if cmd == 'L':
            if value == 270:
                waypoint_x = x_pos + waypoint_rel_y
                waypoint_y = y_pos - waypoint_rel_x

            if value == 180:
                waypoint_x = x_pos - waypoint_rel_x
                waypoint_y = y_pos - waypoint_rel_y

            if value == 90:
                waypoint_x = x_pos - waypoint_rel_y
                waypoint_y = y_pos + waypoint_rel_x

            waypoint_rel_x = waypoint_x - x_pos
            waypoint_rel_y = waypoint_y - y_pos

        if cmd == 'N':
            waypoint_rel_y += value
            waypoint_y = y_pos + waypoint_rel_y

        if cmd == 'S':
            waypoint_rel_y -= value
            waypoint_y = y_pos + waypoint_rel_y

        if cmd == 'E':
            waypoint_rel_x += value
            waypoint_x = x_pos + waypoint_rel_x

        if cmd == 'W':
            waypoint_rel_x -= value
            waypoint_x = y_pos + waypoint_rel_x

    return abs(x_pos) + abs(y_pos)
コード例 #28
0
ファイル: day8.py プロジェクト: nairarunraj/advent_of_code
def puzzle2(input_file) -> int:
    input_content = get_input_data(input_file)

    return execute_instr(input_content, 0, False, 0, {})
コード例 #29
0
ファイル: day24.py プロジェクト: nairarunraj/advent_of_code
def puzzle2(input_file) -> int:
    input_content = get_input_data(input_file)

    tiles = defaultdict(bool)  # False = white, True = black
    start_tile = (0, 0)
    dir_map = {
        'nw': (0.5, 0.5),
        'ne': (-0.5, 0.5),
        'sw': (0.5, -0.5),
        'se': (-0.5, -0.5),
        'e': (-1, 0),
        'w': (1, 0)
    }

    for line in input_content:
        path = []
        prev = ''
        for ch in line:
            if prev in ('n', 's'):
                direction = prev + ch
                prev = ''
                path.append(direction)
                continue

            if ch in ('n', 's'):
                prev = ch
                continue

            path.append(ch)

        current_tile = start_tile
        for nav in path:
            current_tile = get_dir(dir_map, nav, current_tile)

        tiles[current_tile] = not tiles[current_tile]

    for _ in range(100):
        new_tiles = copy.deepcopy(tiles)
        for current_tile in tiles:
            neighbors = get_neighbors(dir_map, current_tile)
            for neighbor in neighbors:
                if neighbor not in tiles:
                    new_tiles[neighbor] = False

        tiles = new_tiles

        to_be_flipped = {}
        for tile, color in tiles.items():
            neighbors = get_neighbors(dir_map, tile)
            assert len(neighbors) == 6
            black_neighbors = 0
            for neighbor in neighbors:
                if neighbor in tiles and tiles[neighbor]:
                    black_neighbors += 1

            if color:  # black
                if black_neighbors == 0 or black_neighbors > 2:
                    to_be_flipped[tile] = False
                continue

            if black_neighbors == 2:
                to_be_flipped[tile] = True

        for tile, color in to_be_flipped.items():
            tiles[tile] = color

    return list(tiles.values()).count(True)