示例#1
0
from code.utils import parse_input

inputs = parse_input(13, '\n', sample=False)

# part one
dt = int(inputs[0])
buses = [int(b) for b in inputs[1].split(',') if b.isnumeric()]
diff = None
cb = None
for bus in buses:
    ct = ((int(dt / bus) + 1) * bus) - dt
    if not diff or ct < diff:
        diff = ct
        cb = bus
print(diff * cb)

# part two
buses2 = []
for bus in inputs[1].split(','):
    if bus.isnumeric():
        buses2.append(int(bus))
    else:
        buses2.append(0)

pairs = [
]  # pairs is a terrible name. This is really something like "buses_with_offsets"
for i in range(len(buses2)):
    pairs.append([buses2[i], i])

pairs = list(reversed(sorted(pairs)))
示例#2
0
from code.utils import parse_input
import re
input = parse_input(17, '\n', sample=False)


XYZW_OFFSETS = []
for ix in (0, -1, 1):
    for iy in (0, -1, 1):
        for iz in (0, -1, 1):
            for iw in (0, -1, 1):
                XYZW_OFFSETS.append([ix, iy, iz, iw])
XYZW_OFFSETS.remove([0,0,0,0])
print(f'num_neighbors is {len(XYZW_OFFSETS)}')


def is_active(x, y, z, w, state):
    if (x not in state or
            y not in state[x] or
            z not in state[x][y] or
            w not in state[x][y][z]):
        return False

    return state[x][y][z][w] == '#'


def calc_new_state(x, y, z, w, state):
    active_neighbors = 0
    for xo, yo, zo, wo in XYZW_OFFSETS:
        if is_active(x+xo, y+yo, z+zo, w+wo, state):
            active_neighbors += 1
示例#3
0
from code.utils import parse_input
import re
nums = parse_input(15, '\n', sample=False)
nums = [int(n) for n in nums[0].split(',')]

max_turn = 2020  # 30000000
last_spoken = {}
spoken_once = set()
spoken_multi = set()
last_num = None


def add_or_remove_from_spoken_once(num):
    if num not in spoken_once and num not in spoken_multi:
        spoken_once.add(num)
    elif num in spoken_once:
        spoken_once.remove(num)
        spoken_multi.add(num)


def add_to_spoken(num, index):
    if num not in last_spoken:
        last_spoken[num] = [index]
    else:
        before = last_spoken[num]
        last_spoken[num] = [before[-1], index]


def get_diff(num):
    if num not in last_spoken:
        return None
示例#4
0
from code.utils import parse_input
import re

bags = parse_input(7, '\n')

### part one
bag_map = {}
bag_count_map = {}
for bag in bags:
    [bag_type, raw_sub] = re.match('(.*)bags contain (.*).', bag).groups()
    bag_type = bag_type.strip()
    raw_sub = raw_sub.split(', ')
    sub_bags = []

    set_sub_bags = set()
    for raw in raw_sub:
        if raw == 'no other bags':
            sub_bags.append([0, None])
        else:
            validated = re.match('(\d+) (.*) bags?', raw).groups()
            sub_bags.append(list(validated))
            set_sub_bags.add(validated[1])

    bag_map[bag_type] = list(set_sub_bags)
    bag_count_map[bag_type] = sub_bags


def contains_gold(bag):
    if bag not in bag_map:
        return False
    if 'shiny gold' in bag_map[bag]:
示例#5
0
from code.utils import parse_input
import re
players = parse_input(22, '\n\n', sample=False)


def get_cards(player_input):
    cards = player_input.split('\n')[1:]
    cards = [int(c) for c in cards]
    return cards


player_cards = [get_cards(i) for i in players]

# part one
while len(player_cards[0]) > 0 and len(player_cards[1]) > 0:
    p1 = player_cards[0].pop(0)
    p2 = player_cards[1].pop(0)

    if p1 > p2:
        player_cards[0].append(p1)
        player_cards[0].append(p2)
    elif p2 > p1:
        player_cards[1].append(p2)
        player_cards[1].append(p1)
    else:
        import ipdb
        ipdb.set_trace()

winning_deck = player_cards[0] + player_cards[1]

total = 0
示例#6
0
from code.utils import parse_input
import re

input = parse_input(19, '\n\n', sample=False)
rules = input[0].split('\n')
lines = input[1].split('\n')

meta_rules = {}
straight_rules = {}
cache = {}


def parse_rules(rules):
    for rule in rules:
        index, logic = rule.split(': ')
        if "\"" in logic:
            straight_rules[index] = logic[1]
        else:
            options = logic.split(" | ")
            for op in options:
                op = op.split(" ")
                if index not in meta_rules:
                    meta_rules[index] = []
                meta_rules[index].append(op)


def add_to_cache(rule_num, matched):
    if rule_num not in cache:
        cache[rule_num] = {matched}
    else:
        cache[rule_num].add(matched)
示例#7
0
from code.utils import parse_input
import re
cup_nums = parse_input(23, '\n', sample=False)[0]
cup_nums = [int(c) for c in cup_nums]

# part one solution
# moves = 100
# num_followers = 3
#
# current_value = cup_nums[0]
#
# def find_index(val):
#     try:
#         return cup_nums.index(val)
#     except:
#         return None
#
#
# for m in range(moves):
#     followers = []
#     for f in range(num_followers):
#         followers.append(cup_nums.pop( (find_index(current_value)+1) % len(cup_nums)))
#
#     dest_val = current_value - 1
#     dest_i = find_index(dest_val)
#     end = False
#     while not end and dest_i is None:
#         dest_val -= 1
#         dest_i = find_index(dest_val)
#         if dest_val <= 0:
#             dest_val = max(cup_nums)
示例#8
0
from code.utils import parse_input
import re
lines = parse_input(14, '\n', sample=False)


def binary_to_int(answer_list):

    return [int(a, 2) for a in answer_list]


def all_permutations(astring):
    if not astring:
        return ['']

    prefix = ''
    suffix = astring

    while len(suffix) > 0 and suffix[0] != 'X':
        prefix += suffix[0]
        suffix = suffix[1:]

    if not suffix:
        fset = set()
        fset.add(prefix)
        return fset

    answers = set()
    suffix_permutations = all_permutations(suffix[1:])
    for perm in suffix_permutations:
        answers.add(prefix + '0' + perm)
        answers.add(prefix + '1' + perm)
示例#9
0
from code.utils import parse_input
input = parse_input(24, '\n', sample=False)

final_tiles = {}

valid_directions = ['e', 'se', 'sw', 'w', 'nw', 'ne']
get_offsets = {
    'e': [0, 2],
    'w': [0, -2],
    'se': [-2, 1],
    'nw': [2, -1],
    'sw': [-2, -1],
    'ne': [2, 1]
}


def parse_dirs(line):
    dirs = []

    curr = ''
    for c in line:
        curr += c

        if curr in valid_directions:
            dirs.append(curr)
            curr = ''

    return dirs


def get_pos(dirs):
示例#10
0
from code.utils import parse_input
import re
foods = parse_input(21, '\n', sample=False)

all_allergens = {}
all_ingredients = []
set_ingredients = set()

for i in range(len(foods)):
    food = foods[i]
    [ingredients, allergens] = food.split(' (contains ')

    ingredients = ingredients.split(' ')
    all_ingredients.append(ingredients)
    for ing in ingredients:
        set_ingredients.add(ing)

    allergens = allergens[:-1].split(', ')
    for allergen in allergens:
        if allergen not in all_allergens:
            all_allergens[allergen] = []
        all_allergens[allergen].append(i)


def intersect(indices):
    inter = set(all_ingredients[indices[0]])
    for i in indices[1:]:
        inter = inter.intersection(set(all_ingredients[i]))

    return inter