예제 #1
0
import sys, os
import re
import operator
from functools import reduce

script_dir = os.path.dirname(__file__)  #<-- absolute dir the script is in
sys.path.append(os.path.join(script_dir, '..', 'common'))
from common import AoCParser, prod

abs_input_filepath = os.path.join(script_dir, 'input.txt')

equations = AoCParser(abs_input_filepath).parse_as_list_of_strings()


# Part 1
def find_end_paren_index(equation, position):
    paren_depth = 0
    start = position
    while position < len(equation):
        if equation[position] == '(':
            paren_depth += 1
        elif equation[position] == ")":
            paren_depth -= 1

        position += 1
        if paren_depth == 0:
            return position


def part_1():
    def evaluate(equation):
예제 #2
0
import sys, os
import re
import operator
from functools import reduce

script_dir = os.path.dirname(__file__)  #<-- absolute dir the script is in
sys.path.append(os.path.join(script_dir, '..', 'common'))
from common import AoCParser, prod

abs_input_filepath = os.path.join(script_dir, 'input.txt')

input = AoCParser(abs_input_filepath).parse_as_list_of_paragraphs()


class Range:
    def __init__(self, range_string):
        [min, max] = range_string.split("-")
        self.min = int(min)
        self.max = int(max)

    def test(self, candidate):
        candidate = int(candidate)
        return candidate >= self.min and candidate <= self.max

    def __repr__(self):
        return "[{}-{}]".format(self.min, self.max)


rule_dict = {}
all_ranges = []
for rule in input[0]:
예제 #3
0
import sys, os
import re

script_dir = os.path.dirname(__file__)  #<-- absolute dir the script is in
sys.path.append(os.path.join(script_dir, '..', 'common'))
from common import AoCParser

abs_input_filepath = os.path.join(script_dir, 'input.txt')

navigation_instruction = AoCParser(
    abs_input_filepath).parse_as_list_of_strings()

# Part 1
# Use a counter, along with a modulo calculation determine the cardinal direction
# Cardinal Direction     Corresponding Remainder
#         N                         0
#       W   E                     3   1
#         S                         2
#


def part_1():
    direction_facing = 1
    x = 0
    y = 0
    for instruction_and_distance in navigation_instruction:
        instruction = re.findall("^[A-Z]", instruction_and_distance)[0]
        distance = int(re.findall("[0-9]+$", instruction_and_distance)[0])

        if instruction == "F":
            if direction_facing % 4 == 0:
예제 #4
0
import sys, os

script_dir = os.path.dirname(__file__)  #<-- absolute dir the script is in
sys.path.append(os.path.join(script_dir, '..', 'common'))
from common import AoCParser

abs_input_filepath = os.path.join(script_dir, 'input.txt')

encoding = AoCParser(abs_input_filepath).parse_as_list_of_ints()


# Part 1
def solve_part_1():
    lookback_distance = 25

    i = lookback_distance
    while i < len(encoding):
        sum_to = encoding[i]
        j = 1
        found_match = False
        while j <= lookback_distance:
            first_candidate = encoding[i - j]
            search_for = sum_to - first_candidate
            if search_for in encoding[i - lookback_distance:i]:
                print("First num: {}".format(first_candidate))
                print("Second num: {}".format(search_for))
                print("Sum to: {}".format(sum_to))
                print("Search space {}".format(encoding[i -
                                                        lookback_distance:i]))
                found_match = True
                break
예제 #5
0
import sys, os

script_dir = os.path.dirname(__file__)  #<-- absolute dir the script is in
sys.path.append(os.path.join(script_dir, '..', 'common'))

abs_input_filepath = os.path.join(script_dir, 'input.txt')

from common import AoCParser

map = AoCParser(abs_input_filepath).parse_as_2d_list()

map_width = len(map[0])


def count_trees_on_slope(step_x, step_y):
    tree_counter = 0
    pos_x = 0
    pos_y = 0
    while pos_y < len(map):
        if pos_x >= map_width:
            pos_x = pos_x % map_width

        if map[pos_y][pos_x] == '#':
            tree_counter += 1

        pos_x = pos_x + step_x
        pos_y = pos_y + step_y

    return tree_counter

예제 #6
0
import sys, os
import re
import operator
from functools import reduce
import math

script_dir = os.path.dirname(__file__)  #<-- absolute dir the script is in
sys.path.append(os.path.join(script_dir, '..', 'common'))
from common import AoCParser, prod

abs_input_filepath = os.path.join(script_dir, 'input.txt')

ingredients_and_allergens_strings = AoCParser(
    abs_input_filepath).parse_as_list_of_strings()

# Parse input and build some useful data structures
ingredient_to_potential_allergens = {}
allergens_to_ingredients = {}
allergen_to_list_of_ingredient_lists = {}
ingredient_lists = []
for line in ingredients_and_allergens_strings:
    [ingredients, allergens] = line[:-1].split(" (contains ")
    ingredients = ingredients.split()
    allergens = allergens.split(", ")
    ingredient_lists.append(ingredients)
    for allergen in allergens:
        if allergen in allergen_to_list_of_ingredient_lists:
            allergen_to_list_of_ingredient_lists[allergen].append(ingredients)
        else:
            allergen_to_list_of_ingredient_lists[allergen] = [ingredients]
        for ingredient in ingredients:
예제 #7
0
import sys, os
import re
import operator
from functools import reduce

script_dir = os.path.dirname(__file__)  #<-- absolute dir the script is in
sys.path.append(os.path.join(script_dir, '..', 'common'))
from common import AoCParser, prod

abs_input_filepath = os.path.join(script_dir, 'input.txt')

[rules, messages] = AoCParser(abs_input_filepath).parse_as_list_of_paragraphs()

# Part 1

rule_bank = {}

#class Rule:
#    def __init__(self, rule_description):
#        [self.rule_num, rule_reqs] = rule_description.split(": ")
#        self.disjunctive_terms = []
#        self.val = None
#        if re.match('"[a-z]"', rule_reqs):
#            self.val = rule_reqs[1]
#            print("Rule {} is a simple rule with val: {}".format(self.rule_num, rule_reqs[1]))
#        elif "|" in rule_reqs:
#            print("Rule {} is a disjunctive rule".format(self.rule_num))
#            [term_1, term_2] = rule_reqs.split(" | ")
#            if " " in term_1:
#                self.disjunctive_terms.append(term_1.split())
#            else:
예제 #8
0
import sys, os
import re
import operator
from functools import reduce
import math
from collections import deque

script_dir = os.path.dirname(__file__)  #<-- absolute dir the script is in
sys.path.append(os.path.join(script_dir, '..', 'common'))
from common import AoCParser, prod

abs_input_filepath = os.path.join(script_dir, 'input.txt')

players_hands = AoCParser(abs_input_filepath).parse_as_list_of_paragraphs()

player_1_hand = deque([int(card) for card in players_hands[0][1:]])
player_2_hand = deque([int(card) for card in players_hands[1][1:]])


def play_combat():
    while len(player_1_hand) > 0 and len(player_2_hand) > 0:
        player_1_card = player_1_hand.popleft()
        player_2_card = player_2_hand.popleft()

        if player_1_card > player_2_card:
            player_1_hand.append(player_1_card)
            player_1_hand.append(player_2_card)
        else:
            player_2_hand.append(player_2_card)
            player_2_hand.append(player_1_card)
예제 #9
0
import sys, os

script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in
sys.path.append(os.path.join(script_dir, '..', 'common'))
from common import AoCParser

abs_input_filepath = os.path.join(script_dir, 'input.txt')

adapter_ratings = AoCParser(abs_input_filepath).parse_as_list_of_ints()

# Part 1
adapter_ratings.sort()

cur = 0
cumulative_difference = 0
diff_1 = 0
diff_3 = 0
for index in range(len(adapter_ratings)):
    difference = adapter_ratings[index] - cur
    cumulative_difference += difference
    cur = cumulative_difference
    if difference == 1:
        diff_1 += 1
    if difference == 3:
        diff_3 += 1


cumulative_difference += 3
diff_3 += 1

print(cumulative_difference)
예제 #10
0
import sys, os
import re
import operator
from functools import reduce
import math
from collections import deque
from itertools import cycle

script_dir = os.path.dirname(__file__)  #<-- absolute dir the script is in
sys.path.append(os.path.join(script_dir, '..', 'common'))
from common import AoCParser, prod

abs_input_filepath = os.path.join(script_dir, 'input.txt')

public_keys = AoCParser(abs_input_filepath).parse_as_list_of_ints()

card_public_key = public_keys[0]
door_public_key = public_keys[1]


# Part 1
def part_1():
    value = 1

    def transform(value, subject_number):
        value *= subject_number
        return value % 20201227

    secret_loop_counter = 0
    while value != card_public_key:
        value = transform(value, 7)
예제 #11
0
import sys, os
import re

script_dir = os.path.dirname(__file__)  #<-- absolute dir the script is in
sys.path.append(os.path.join(script_dir, '..', 'common'))
from common import AoCParser

abs_input_filepath = os.path.join(script_dir, 'input.txt')

encoded_boarding_passes = AoCParser(
    abs_input_filepath).parse_as_list_of_strings()


def decode(min_row, max_row, encoded_row):
    for step in encoded_row:
        #print("min: {}, max: {}, candidates remaining: {}".format(min_row, max_row, max_row - min_row + 1))
        if (step == 'F' or step == 'L'):
            max_row = int((min_row + max_row) / 2)
        elif (step == 'B' or step == 'R'):
            min_row = int((min_row + max_row) / 2) + 1

    if min_row == max_row:
        return min_row


def decode_row(encoded_row):
    return decode(0, 127, encoded_row)


def decode_col(encoded_col):
    return decode(0, 7, encoded_col)
예제 #12
0
import sys, os
import re
import operator
from functools import reduce
import math
from collections import deque
from itertools import cycle

script_dir = os.path.dirname(__file__)  #<-- absolute dir the script is in
sys.path.append(os.path.join(script_dir, '..', 'common'))
from common import AoCParser, prod

abs_input_filepath = os.path.join(script_dir, 'input.txt')

input_cups = AoCParser(
    abs_input_filepath).parse_as_single_line_of_undelimited_ints()


def part_1(cups, iterations):
    def remove_3_cups(current_cup_index):
        cup_indices = [current_cup_index + i for i in [1, 2, 3]]
        cup_indices = [cup_index % len(cups) for cup_index in cup_indices]
        removed_cups = [cups[i] for i in cup_indices]
        [cups.remove(cup) for cup in removed_cups]
        return removed_cups

    def get_destination_cup(current_cup):
        cups_less_than_current_cup = [cup for cup in cups if cup < current_cup]
        if len(cups_less_than_current_cup) == 0:
            return max(cups)
        return max(cups_less_than_current_cup)