예제 #1
0
def check_allergens():
    recipy_list = util.parse_file_as_list(ingredients_file)

    ingredients_allergens_split = [
        recipy.split(' (contains ') for recipy in recipy_list
    ]
    allergens_ingredients_sets = [[
        set(row[1].replace(')', '').split(', ')),
        set(row[0].split(' '))
    ] for row in ingredients_allergens_split]

    # map allergen to each set it is named in
    allergen_ingredients_dict = {}
    all_ingredients_set = set()
    combined_recipe_list = []
    for allergen_set, ingredient_set in allergens_ingredients_sets:
        for allergen in allergen_set:
            if allergen not in allergen_ingredients_dict:
                allergen_ingredients_dict[allergen] = []
            allergen_ingredients_dict[allergen].append(ingredient_set)
        all_ingredients_set |= ingredient_set
        combined_recipe_list.extend(list(ingredient_set))

    # check which allergens intersect only on one ingredient in their sets
    determined_allergen_ingredient_dict = {}
    all_allergens_set = set(allergen_ingredients_dict.keys())
    while len(all_allergens_set) > 0:
        for allergen, recipes in allergen_ingredients_dict.items():
            # skip ingredients already found
            if allergen not in determined_allergen_ingredient_dict:
                # remove found allergens from intersection
                intersection = set.intersection(*recipes).difference(
                    set(determined_allergen_ingredient_dict.values()))

                if len(intersection) == 1:
                    determined_allergen_ingredient_dict[
                        allergen] = intersection.pop()
                    all_allergens_set.remove(allergen)

    # count occurrences of non-allergen ingredients
    safe_ingredients_set = all_ingredients_set.difference(
        set(determined_allergen_ingredient_dict.values()))
    ingredient_counts = [
        combined_recipe_list.count(ingredient)
        for ingredient in safe_ingredients_set
    ]

    print(determined_allergen_ingredient_dict)
    print(sum(ingredient_counts))

    danger_list = list(determined_allergen_ingredient_dict.keys())
    danger_list.sort()
    poison_string = ''
    for danger in danger_list:
        poison_string += determined_allergen_ingredient_dict.get(danger) + ','
    print(poison_string)
예제 #2
0
def check_passwords():
    password_file_list = util.parse_file_as_list(file=password_file)
    policy_password_lists = [line.split(':') for line in password_file_list]
    correct_password_count = 0
    for policy, password in policy_password_lists:
        num_range, char = policy.split(' ')
        min_count, max_count = num_range.split('-')
        if int(min_count) <= password.count(char) <= int(max_count):
            correct_password_count += 1
    print(correct_password_count)
예제 #3
0
def flip_it():
    string_list = util.parse_file_as_list(real_file)

    the_grid = Grid()
    for direction_string in string_list:
        the_grid.parse_direction_string(direction_string)
        the_grid.goto_start()
    the_grid.print_hexagons()

    for x in range(100):
        the_grid.daily_flip()
    the_grid.print_hexagons()
예제 #4
0
def battle():
    parsed_file = util.parse_file_as_list(decks)

    player_1_deck = [int(value) for value in parsed_file[1:26]]
    player_2_deck = [int(value) for value in parsed_file[28:]]

    winner = play_recursive_game(player_1_deck, player_2_deck)
    score = 0
    if winner == 1:
        score = calculate_score(player_1_deck)
    elif winner == 2:
        score = calculate_score(player_2_deck)
    return score
예제 #5
0
def parse_seat_ids():
    seats_lists = [
        line.translate(str.maketrans({
            'F': '0',
            'L': '0',
            'B': '1',
            'R': '1'
        })) for line in util.parse_file_as_list(seats_file)
    ]
    seat_ids = [int(x, 2) for x in seats_lists]
    my_seat = set(range(80, int('1' * 10, 2))) - set(seat_ids)
    print(max(seat_ids))
    print(min(my_seat))
예제 #6
0
def check_passwords_part_2():
    password_file_list = util.parse_file_as_list(file=password_file)
    policy_password_lists = [line.split(':') for line in password_file_list]
    correct_password_count = 0
    for policy, password in policy_password_lists:
        password = password.strip()
        num_range, char = policy.split(' ')
        char_index_1, char_index_2 = num_range.split('-')
        a = password[int(char_index_1) - 1]
        b = password[int(char_index_2) - 1]
        if (a == char and b != char) or (b == char and a != char):
            correct_password_count += 1
    print(correct_password_count)
예제 #7
0
def sort_adapters():
    adapter_list = [int(num) for num in util.parse_file_as_list(adapter_file)]
    adapter_list.append(0)
    adapter_list.append(max(adapter_list) + 3)
    adapter_list.sort(reverse=True)
    jolt_diffs = [
        adapter_list[index - 1] - adapter
        for index, adapter in enumerate(adapter_list) if index > 0
    ]
    three_indices = [index for index, num in enumerate(jolt_diffs) if num == 3]
    three_indices.append(len(jolt_diffs))
    three_index_diffs = [
        x - three_indices[index - 1] for index, x in enumerate(three_indices)
        if index > 0
    ]
    combination_dict = {5: 7, 4: 4, 3: 2, 2: 1, 1: 1}
    total_combinations = reduce(
        mul, [combination_dict.get(num) for num in three_index_diffs])
    return jolt_diffs.count(1), jolt_diffs.count(3), total_combinations
예제 #8
0
import util
import re

homework = util.parse_file_as_list('input_files/day_18.txt')


def alternate_math():
    prepped_homework = [line.replace('))', ') )') for line in homework]
    return sum(
        [walk_the_line(line.split(' '), 0)[0] for line in prepped_homework])


def walk_the_line(operator_list, total_value, index=0):
    operator = ''
    while index < len(operator_list):
        value = operator_list[index]
        if value.isdigit() and total_value == 0:
            total_value = int(value)
        elif value.isdigit():
            total_value = eval(str(total_value) + operator + value)
        elif value in ('+', '*'):
            operator = value
        elif value.startswith('('):
            operator_list[index] = value[1:]
            sub_total, end_index = walk_the_line(operator_list, 0, index=index)
            operator_list[index + 1:end_index] = [str(sub_total)]
        elif value.endswith(')'):
            if value != ')':
                total_value = eval(
                    str(total_value) + operator + value.strip(')'))
            return total_value, index + 1
예제 #9
0
import itertools
import util

program_file = util.parse_file_as_list('input_files/day_14.txt')
mem = {}


def read_program():
    bitmask = ''
    for line in program_file:
        if line.startswith('mask'):
            bitmask = line.lstrip('mask = ')
        elif line.startswith('mem'):
            address, value = line.split('] = ')
            mem_index = int(address.lstrip('mem['))
            # bin_value, original_bin_length = format_value(value, mem_index)
            bin_value = format(int(mem_index), 'b').zfill(36)
            mask_decode(bin_value, bitmask, value)
            # masked_bin_value = apply_mask(bin_value, bitmask)
            # mem[mem_index] = masked_bin_value
    return sum([int(value) for value in mem.values()])


def format_value(bin_value, mem_index):
    bin_value = format(int(bin_value), 'b')
    original_bin_length = len(bin_value)
    if len(bin_value) < 36 - mem_index:
        needed_pad = 36 - mem_index - len(bin_value)
        bin_value = bin_value.rjust(needed_pad, '0')
    bin_value = bin_value.zfill(36)
    return bin_value, original_bin_length
예제 #10
0
import util

movement_list = util.parse_file_as_list('input_files/day_12.txt')


class Ship:
    def __init__(self, directions=movement_list):
        self.directions = [(direction[0], int(direction[1:]))
                           for direction in directions]
        self.position = {'N': 0, 'S': 0, 'E': 0, 'W': 0}
        self.coordinates = {'W': 0, 'N': 0}
        self.waypoint_position = {'N': 1, 'S': 0, 'E': 10, 'W': 0}
        self.waypoint_coordinates = {'E': 10, 'N': 1}
        self.wind_direction_dict = {0: 'N', 90: 'E', 180: 'S', 270: 'W'}
        self.heading = 90  # initial heading is east

    def set_sail(self):  # just follow the map without thinking
        for action, value in self.directions:
            if action in self.position.keys():
                self.position[action] += value
            elif action == 'R':
                self.heading = (self.heading + value) % 360
            elif action == 'L':
                self.heading = (self.heading - value) % 360
            elif action == 'F':
                self.position[self.wind_direction_dict.get(
                    self.heading)] += value
        print('Our current Manhatten position is: ' +
              str(abs(self.position.get('N') - self.position.get('S'))) +
              ', ' + str(abs(self.position.get('W') - self.position.get('E'))))
예제 #11
0
import util
from itertools import product, starmap, combinations_with_replacement, accumulate
number_file = 'input_files/day_9.txt'
number_list = [int(num) for num in util.parse_file_as_list(number_file)]


def find_weakness(preamble=25):
    for index, num in enumerate(number_list):
        if index > preamble - 1:
            all_possible_permutations = {
                x + y
                for x in number_list[index - preamble:]
                for y in number_list[index - preamble:]
            }
            if num not in all_possible_permutations:
                return num


def determine_weakness(weak_num):
    combination_size = 2
    while True:
        for index, value in enumerate(number_list, combination_size):
            if sum(number_list[index - combination_size:index]) == weak_num:
                return min(number_list[index - combination_size:index]) + max(
                    number_list[index - combination_size:index])
            index += 1
        combination_size += 1
예제 #12
0
arrival station: 47-269 or 282-949
arrival platform: 26-500 or 521-960
arrival track: 26-681 or 703-953
class: 49-293 or 318-956
duration: 25-861 or 873-973
price: 30-446 or 465-958
route: 50-525 or 551-973
row: 39-129 or 141-972
seat: 37-566 or 573-953
train: 43-330 or 356-969
type: 32-770 or 792-955
wagon: 47-435 or 446-961
zone: 30-155 or 179-957
'''

nearby_tickets = util.parse_file_as_list('input_files/day_16.txt')
your_ticket = [
    '71', '127', '181', '179', '113', '109', '79', '151', '97', '107', '53',
    '193', '73', '83', '191', '101', '89', '149', '103', '197'
]


def get_rules():
    validation_dict = {}
    for rule in validation_rules.splitlines():
        rule_name, values = rule.split(':')
        range_values = [
            number.strip() for value in values.split(' or ')
            for number in value.split('-')
        ]
        validation_code_string = 'x in range({0}, {1} + 1) or x in range({2}, {3} + 1)'.format(
예제 #13
0
def tassies():
    bag_rules = [rule.replace('bags', '').replace('bag', '') for rule in util.parse_file_as_list(bag_file)]
    return {pappies.strip(): {kiddo[3:].strip(): kiddo[1] for kiddo in kiddies.split(',')} for pappies, kiddies in [rule.strip('.').split('contain') for rule in bag_rules]}
예제 #14
0
import util
import numpy

seat_file = 'input_files/day_11.txt'
seat_list = util.parse_file_as_list(seat_file)


def seat_the_people(seat_list=seat_list, max_occupied=5, distance=int(10e12)):
    seat_map = {(x, y): char
                for y, line in enumerate(seat_list)
                for x, char in enumerate(line)}
    the_matrix = numpy.array([list(line) for line in seat_list])
    still_movin_around = True
    while still_movin_around:
        still_movin_around = False
        locations_to_change = {}
        for location, char in seat_map.items():
            if char != '.':
                coords_to_check = check_matrix(the_matrix, location[0],
                                               location[1], distance)
                if coords_to_check.count('#') >= max_occupied and char == '#':
                    locations_to_change[location] = 'L'
                elif coords_to_check.count('#') == 0 and char == 'L':
                    locations_to_change[location] = '#'
        if len(locations_to_change) > 0:
            still_movin_around = True
            for loc, new_value in locations_to_change.items():
                seat_map[loc] = new_value
                the_matrix[loc[1]][loc[0]] = new_value
    return sum([1 for hekje in seat_map.values() if hekje == '#'])
예제 #15
0
 def read_instructions(self, file):
     return [
         self.Instruction(operation=instruction.split(' ')[0],
                          value=instruction.split(' ')[1])
         for instruction in util.parse_file_as_list(file)
     ]
예제 #16
0
import util
import math

raw_schedule = util.parse_file_as_list('input_files/day_13.txt')


def check_schedule():
    departure_time = int(raw_schedule[0])
    bus_ids = [
        int(bus_id) for bus_id in raw_schedule[1].split(',') if bus_id != 'x'
    ]
    bus_wait_times = {}
    for bus_id in bus_ids:
        wait_time = bus_id - (departure_time % bus_id)
        bus_wait_times[bus_id] = wait_time
    return bus_wait_times


def diff_approach():
    bus_id_time_offset_dict = {
        int(bus_id): time_offset
        for time_offset, bus_id in enumerate(raw_schedule[1].split(','))
        if bus_id != 'x'
    }
    bus_ids = [bus_id for bus_id in bus_id_time_offset_dict.keys()]
    bus_ids.sort()
    common_denom = bus_ids[0]
    first_occ = 0
    for index, bus_id in enumerate(bus_ids):
        if index > 0:
            this_buss_offset = bus_id_time_offset_dict.get(bus_id)
예제 #17
0
import util
import re

test_rules = [
    '0: 4 1 5', '1: 2 3 | 3 2', '2: 4 4 | 5 5', '3: 4 5 | 5 4', '4: "a"',
    '5: "b"', '', 'ababbb', 'bababa', 'abbbab', 'aaabbb', 'aaaabbb'
]

twest_rules = util.parse_file_as_list('input_files/day_19_part_2.txt')

the_rules = util.parse_file_as_list('input_files/day_19.txt')


class Node:
    def __init__(self, left=None, right=None):
        self.left = left
        self.right = right
        self.value = None
        self.parent = None
        self.str_list = []
        self.end_nodes = []

    def __repr__(self):
        return 'Node value: ' + str(self.value)

    def add_child(self, value=None, go_right=False):
        child = Node()
        child.parent = self
        child.value = value

        if go_right:
예제 #18
0
import util

tree_file = 'input_files/day_3.txt'
tree_file_list = util.parse_file_as_list(file=tree_file)

test_map = [
    '..##.......', '#...#...#..', '.#....#..#.', '..#.#...#.#', '.#...##..#.',
    '..#.##.....', '.#.#.#....#', '.#........#', '#.##...#...', '#...##....#',
    '.#..#...#.#'
]


def count_trees_on_slope_part_1(right, down):
    return sum([
        1 for index, line in enumerate(tree_file_list) if index %
        down == 0 and line[round(((index * right) / down)) % len(line)] == '#'
    ])


def count_trees_on_slope_part_2():
    input_array = [(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)]
    print([
        count_trees_on_slope_part_1(right, down) for right, down in input_array
    ])
예제 #19
0
import util
import numpy as np
import itertools

test_dimension = ['.#.', '..#', '###']

start_dimension = util.parse_file_as_list('input_files/day_17.txt')


def enter_the_matrix_again(dimensions=4):
    universe = np.array([[1 if char == '#' else 0 for char in line]
                         for line in start_dimension],
                        ndmin=dimensions)
    for loops in range(6):
        universe = another_dimension(universe)
    return universe.sum()


def expand_the_universe(universe):
    #  order of position in matrix is z, y, x
    z, y, x = universe.shape

    expanded_universe = np.array(np.zeros((z + 4, y + 4, x + 4)))
    expanded_universe[2:-2, 2:-2, 2:-2] = universe
    the_newlyverse = np.array(np.zeros((z + 4, y + 4, x + 4)))

    for cube_coords in itertools.product(
            range(1, z + 3), itertools.product(range(1, x + 3), repeat=2)):
        z, y_x = cube_coords
        y, x = y_x
        cube_value = expanded_universe[z, y, x]