Ejemplo n.º 1
0
from get_input import get

sues = get(16).split('\n')

correct_sue = {
    'children': 3,
    'cats': 7,
    'samoyeds': 2,
    'pomeranians': 3,
    'akitas': 0,
    'vizslas': 0,
    'goldfish': 5,
    'trees': 3,
    'cars': 2,
    'perfumes': 1
}


def correct(attr, val, part1=True):
    if part1:
        return correct_sue[attr] == int(val)
    if attr in ['cats', 'trees']:
        return int(val) > correct_sue[attr]
    elif attr in ['pomeranians', 'goldfish']:
        return int(val) < correct_sue[attr]
    else:
        return correct_sue[attr] == int(val)


for sue in sues:
    attributes = sue.replace(',', '').replace(':', '').split(' ')
Ejemplo n.º 2
0
from get_input import get
import re
import itertools
p_input = get(14).split('\n')

memory = {}

for l in p_input:
    l = l.replace(" ", "").split('=')
    if l[0] == 'mask':
        mask = l[1]
        and_mask = int(mask.replace('X', '1'), 2)
        or_mask = int(mask.replace('X', '0'), 2)
    else:
        addr = re.findall('\d+', l[0])[0]
        val = and_mask & int(l[1]) | or_mask
        memory[addr] = int(val)

ans = sum(memory.values())

print("Day fourteen part one: {}".format(ans))

memory = {}

for l in p_input:
    l = l.replace(" ", "").split('=')
    if l[0] == 'mask':
        mask = l[1]
        or_mask = int(mask.replace('X', '0'), 2)
    else:
        val = int(l[1])
Ejemplo n.º 3
0
from get_input import get

input = get(1)
print(sum([-1 if i == ')' else 1 for i in input]))

floor = 0

for (x, i) in enumerate(input):
    floor += 1 if i == '(' else -1
    if (floor < 0):
        print(x + 1)
        break
Ejemplo n.º 4
0
from get_input import get
import numpy as np

p_input = list(get(11).replace('\n', ''))

width = len(get(11).split('\n')[0])
height = len(get(11).split('\n'))


def valid(index, d, step):
    (x, y) = d
    i = index // width
    j = index % width
    return i + x * step >= 0 and i + x * step < height and j + y * step >= 0 and j + y * step < width


def neighbours(index, first=True):
    i = index // width
    j = index % width
    ns = [(i - 1, j - 1), (i, j - 1), (i + 1, j - 1), (i - 1, j), (i + 1, j),
          (i - 1, j + 1), (i, j + 1), (i + 1, j + 1)]
    dirs = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1),
            (1, 1)]
    if i == 0:
        ns = [
            el for el in ns
            if el not in {(i - 1, j - 1), (i - 1, j), (i - 1, j + 1)}
        ]
        dirs = [el for el in dirs if el not in {(-1, -1), (-1, 0), (-1, 1)}]
    if j == 0:
        ns = [
Ejemplo n.º 5
0
from get_input import get
p_input = get(16).split('\n')

my_ticket = [int(i) for i in p_input[22].split(',')]

valids = set()
fields = []

for (i, l) in enumerate(p_input):
    if not l:
        next_start = i
        break
    words = l.split(' ')
    first = words[-3].split('-')
    first = (int(first[0]), int(first[1]))
    second = words[-1].split('-')
    second = (int(second[0]), int(second[1]))
    numbers = []
    for i in range(first[0], first[1] + 1):
        valids.add(i)
        numbers.append(i)
    for i in range(second[0], second[1] + 1):
        valids.add(i)
        numbers.append(i)
    fields.append(numbers)

invalids = []
badidx = []

for (i, l) in enumerate(p_input[next_start + 5:]):
    ticket = [int(j) for j in l.split(',')]
Ejemplo n.º 6
0
from get_input import get

p_word = get(11)

alphabet = 'abcdefghijklmnopqrstuvwxyz'
forbidden = 'iol'

def increment(string):
    s = list(string)
    for i in range(len(s)-1, -1, -1):
        letter = s[i]
        letter_index = alphabet.index(letter)
        new_index = (letter_index + 1) % len(alphabet)
        new_letter = alphabet[new_index]
        if new_letter in forbidden:
            new_index += 1
            new_letter = alphabet[new_index]

        s[i] = new_letter
        if new_letter != 'a':
            return ''.join(s)

def increasing(string):
    [i, j, k] = [alphabet.index(string[0]), alphabet.index(string[1]), alphabet.index(string[2])]
    return j == i+1 and k == j+1


def valid(string):
    trips = [string[i] + string[i+1] + string[i+2] for i in range(len(string)-2)]
    if not any([increasing(t) for t in trips]):
        return False
Ejemplo n.º 7
0
from get_input import get
p_input = get(18).split('\n')


def ev(term):
    term = term.replace('(', "").replace(')', "")
    term = term.split(' ')
    acc = int(term[0])
    i = 1
    while i < len(term):
        t = term[i]
        if t == '+':
            acc += int(term[i + 1])
            i += 2
        if t == '*':
            acc *= int(term[i + 1])
            i += 2
    return str(acc)


def calc(terms):
    terms2 = terms.copy()
    rem = []
    for t in terms[:-1]:
        res = ev(t)
        if any([t in ts for ts in terms if t != ts]):
            terms[i] = ts.replace(t, res)
            rem.append(t)

    for r in rem:
        terms2.remove(rem)
Ejemplo n.º 8
0
from get_input import get
p_input = get(12).split('\n')

dir_map = {'E': 0, 'S': 1, 'W': 2, 'N': 3, 0: 'E', 1: 'S', 2: 'W', 3: 'N'}

directions = {'E': (1, 0), 'S': (0, 1), 'W': (-1, 0), 'N': (0, -1)}


def move(dir, dist):
    (x, y) = dir
    dx = x * dist
    dy = y * dist
    return (dx, dy)


def run(first=True):
    waypoint = (0, 0) if first else (10, -1)
    ship = (0, 0)
    facing = 'E'
    for l in p_input:
        direction = l[0]
        value = int(l[1:])
        rotations = 0
        if direction in ['E', 'S', 'W', 'N']:
            (x, y) = move(directions[direction], value)
            waypoint = (waypoint[0] + x, waypoint[1] + y)
        elif direction == 'L' and first:
            rotations = -(value // 90)
        elif direction == 'R' and first:
            rotations = value // 90
        elif direction == 'L' and not first:
Ejemplo n.º 9
0
from get_input import get

grid = []
for i in range(1000):
    grid.append([0] * 1000)

input = get(6).split('\n')

ans = 0
for line in input:
    line = line.split(' ')
    end = [int(i) for i in line[-1].split(',')]
    start = [int(i) for i in line[-3].split(',')]
    for i in range(start[0], end[0] + 1):
        for j in range(start[1], end[1] + 1):
            if line[0] == 'turn':
                if line[1] == 'on':
                    grid[i][j] = 1
                else:  # line[1] == 'off'
                    grid[i][j] = 0
            else:  #line[0] == 'toggle'
                grid[i][j] = 0 if grid[i][j] else 1

print(sum([sum(line) for line in grid]))

grid = []
for i in range(1000):
    grid.append([0] * 1000)

for (k, line) in enumerate(input):
    line = line.split(' ')
Ejemplo n.º 10
0
from get_input import get
from numpy import prod
p_input = get(3).split("\n")

width = len(p_input[0])
height = len(p_input)

slopes = [(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)]

n_trees = []
for s in slopes:
    dx = s[0]
    dy = s[1]
    t = 0
    x = 0
    y = 0
    while y < height:
        if p_input[y][x % width] == '#':
            t += 1
        x += dx
        y += dy
    n_trees.append(t)

print("Day three part one: {}".format(n_trees[1]))
print("Day three part two: {}".format(prod(n_trees)))
Ejemplo n.º 11
0
from get_input import get
import re

input = get(8).split('\n')

sum_code = 0
sum_char = 0
sum_char2 = 0
ascii_regex = r'\\x[0-9a-f]{2}'
other_regex = r'\\"|\\\\'

for line in input:
    sum_code += len(line)
    formatted_line = re.sub(other_regex, '$', line)
    formatted_line = re.sub(ascii_regex, '$', formatted_line)
    sum_char += len(formatted_line) - 2

    elongated_line = '\"' + line.replace('\\', '\\\\').replace('\"',
                                                               '\\\"') + '\"'
    sum_char2 += len(elongated_line)

print(sum_code - sum_char)
print(sum_char2 - sum_code)
Ejemplo n.º 12
0
from get_input import get
import re

input = get(19).split('\n')

molecule = input[-1]
recipes = input[:-2]

substitutions = {}
new_molecules = set()
upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

for line in recipes:
    line = line.split(' ')
    orig = line[0]
    substitution = line[2]
    if orig not in substitutions.keys():
        substitutions[orig] = [substitution]
    else:
        substitutions[orig].append(substitution)
    if orig not in molecule:
        continue
    l = len(orig)
    substrings = [molecule[i:i + l] for i in range(len(molecule) - l + 1)]
    appearances = [i for i in range(len(substrings)) if substrings[i] == orig]
    for index in appearances:
        prefix = molecule[:index]
        suffix = molecule[index + l:]
        new_string = prefix + substitution + suffix
        new_molecules.add(new_string)
Ejemplo n.º 13
0
from get_input import get
import re

p_input = get(4).split("\n")

people1 = []
people2 = []
person = {}
keys = ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid']

def check1(person):
    return all([k in person for k in keys])

def check2(person):
    return all([valid(k, person[k]) for k in keys])

def valid(key, value):
    if key == 'byr':
        return int(value) >= 1920 and int(value) <= 2002
    elif key == 'iyr':
        return int(value) >= 2010 and int(value) <= 2020
    elif key == 'eyr':
        return int(value) >= 2020 and int(value) <= 2030
    elif key == 'hgt':
        if value[-2:] == 'cm':
            return int(value[:-2]) >= 150 and int(value[:-2]) <= 193
        elif value[-2:] == 'in':
            return int(value[:-2]) >= 59 and int(value[:-2]) <= 76
        else:
            return False
    elif key == 'hcl':
Ejemplo n.º 14
0
from get_input import get
p_input = [int(i) for i in get(15).split(',')]

spoken = {}
for (i, p) in enumerate(p_input[:-1]):
    spoken[p] = i + 1

last = p_input[-1]
for i in range(len(spoken) + 2, 30000001):
    if i == 2021:
        print("Day fifteen part one: {}".format(last))
    if last in spoken:
        sp = i - 1 - spoken[last]
    else:
        sp = 0
    spoken[last] = i - 1
    last = sp

print("Day fifteen part one: {}".format(last))
Ejemplo n.º 15
0
from get_input import get
p_input = get(17).split('\n')

actives = set()
y = 0
z = 0
for line in p_input:
    x = 0
    for char in line:
        if char == '#':
            actives.add((x, y, z))
        x += 1
    y += 1

for cycle in range(6):
    new_actives = set()

    zs = [z for (x, y, z) in actives]
    ys = [y for (x, y, z) in actives]
    xs = [x for (x, y, z) in actives]

    for z in range(min(zs) - 1, max(zs) + 2):
        for y in range(min(ys) - 1, max(ys) + 2):
            for x in range(min(xs) - 1, max(xs) + 2):
                is_active = (x, y, z) in actives
                active_neighbours = 0

                for z2 in range(z - 1, z + 2):
                    for y2 in range(y - 1, y + 2):
                        for x2 in range(x - 1, x + 2):
                            if (x, y, z) == (x2, y2, z2):
Ejemplo n.º 16
0
from get_input import get
import re
import json

input = get(12)

number_regex = r'[-0-9]+'

print(sum([int(m) for m in re.findall(number_regex, input)]))


json_input = json.loads(input)

def count_recursive(root):
    if isinstance(root, int):
        return root
    elif isinstance(root, str):
        return 0
    elif isinstance(root, list):
        return sum([count_recursive(i) for i in root])
    else: #isinstance(root, dict):
        if 'red' in [root[k] for k in root]:
            return 0
        else: 
            return sum([count_recursive(root[k]) for k in root])

print(count_recursive(json_input))


    
Ejemplo n.º 17
0
from get_input import get
from interpreter import run, preprocess
p_input = preprocess(get(8).split('\n'))

acc, visited, pc = run(p_input, set(), 0)

print("Day eight part one: {}".format(acc))

nops = [i for (i, (op, _)) in enumerate(p_input) if op == 'nop']
jmps = [i for (i, (op, _)) in enumerate(p_input) if op == 'jmp']


def brute(op):
    if op == 'nop':
        ops = nops = [i for (i, (op, _)) in enumerate(p_input) if op == 'nop']
    else:
        ops = jmps = [i for (i, (op, _)) in enumerate(p_input) if op == 'jmp']
    for o in ops:
        p_copy = p_input.copy()
        p_copy[o] = ('jmp' if op == 'nop' else 'nop', p_copy[o][1])
        acc, visited, pc = run(p_copy, set(), 0)
        if pc == len(p_copy):
            return acc


acc = brute('nop')
if not acc:
    acc = brute('jmp')

print("Day eight part two: {}".format(acc))
Ejemplo n.º 18
0
from get_input import get

p_input = get(2).split("\n")

n_okay1 = 0
n_okay2 = 0

for line in p_input:
    l = line.split(" ")
    numbers = [int(i) for i in l[0].split("-")]
    letter = l[1][0]
    pword = l[2]
    count = pword.count(letter)
    if count >= numbers[0] and count <= numbers[1]:
        n_okay1 += 1

    i1 = numbers[0] - 1
    i2 = numbers[1] - 1
    if (pword[i1] == letter) ^ (pword[i2] == letter):
        n_okay2 += 1

print("Day two part one: {}".format(n_okay1))
print("Day two part two: {}".format(n_okay2))
Ejemplo n.º 19
0
from get_input import get
p_input = get(5).split('\n')
ids = []

for l in p_input:
    row = ''.join(['1' if k == 'B' else '0' for k in l[:-3]])
    col = ''.join(['1' if k == 'R' else '0' for k in l[-3:]])
    id = int(row, 2) * 8 + int(col, 2)
    ids.append(id)

highest = max(ids)
print("Day five part one: {}".format(highest))
nums = list(range(min(ids), highest))
diff = set(nums).symmetric_difference(set(ids)).pop()
print("Day five part two: {}".format(diff))





    
Ejemplo n.º 20
0
from get_input import get
p_input = sorted([int(i) for i in get(10).split('\n')])

ones = 0
threes = 0

outlet = 0
device = p_input[-1] + 3
p_input.append(device)
p_input = [outlet] + p_input
i = 1

while i < len(p_input):
    diff = p_input[i] - p_input[i - 1]
    if diff == 1:
        ones += 1
    elif diff == 3:
        threes += 1
    else:
        print("broken")
        break
    i += 1

print("Day ten part one: {}".format(ones * threes))

ways = [0] * max(p_input)
ways[-1] = 1

i = len(p_input) - 2

for i in reversed(p_input[:-1]):
Ejemplo n.º 21
0
from get_input import get

p_input = [int(i) for i in get(1).split('\n')]
p_input.sort()

target = 2020


def p1():
    i = 0
    j = len(p_input) - 1
    while i != j:
        s = p_input[i] + p_input[j]
        if s == target:
            return p_input[i] * p_input[j]
        elif s > target:
            j -= 1
        else:  # s < target
            i += 1


def p2():
    for (i, _) in enumerate(p_input):
        j = i + 1
        k = len(p_input) - 1
        while j != k:
            s = p_input[i] + p_input[j] + p_input[k]
            if s == target:
                return p_input[i] * p_input[j] * p_input[k]
            elif s > target:
                k -= 1
Ejemplo n.º 22
0
from get_input import get
from itertools import combinations

containers = sorted([int(c) for c in get(17).split('\n')])
amount = 150

for i in range(1, len(containers)):
    if sum(containers[:-i]) < amount:
        longest = len(containers) - i
        break

for i in range(1, len(containers)):
    if sum(containers[-i:]) > amount:
        shortest = i
        break

n_matches = 0
for size in range(shortest, longest + 1):
    n_matches += sum(
        [sum(c) == amount for c in combinations(containers, size)])
    if size == shortest:
        second_answer = n_matches

print(n_matches)
print(second_answer)
Ejemplo n.º 23
0
from get_input import get
import hashlib

input = get(4)

counter = 1
found = [False, False]
threshold = 5
while not all(found):
    string = input + str(counter)
    hex = hashlib.md5(string.encode()).hexdigest()
    if not found[0] and hex[:5] == '00000':
        print(counter, hex)
        found[0] = True

    if not found[1] and hex[:6] == '000000':
        print(counter, hex)
        found[1] = True

    counter += 1
Ejemplo n.º 24
0
from get_input import get

input = get(10)

seq = input

for i in range(50):
    group = []
    group.append([seq[0]])
    for n in seq[1:]:
        if n == group[-1][0]:
            group[-1].append(n)
        else: 
            group.append([n])

    seq = ''
    for g in group:
        seq += str(len(g)) + g[0]

    if i == 39:
        print(len(seq))
    if i == 49:
        print(len(seq))

Ejemplo n.º 25
0
from get_input import get
from itertools import combinations
from math import ceil

# Returns true if p1 wins, false otherwise
def fight(p1, p2):
    p1_actual_damage = max(1, p1['damage'] - p2['armor'])
    p2_actual_damage = max(1, p2['damage'] - p1['armor'])
    p1_rounds = ceil(p2['hp'] / p1_actual_damage)
    p2_rounds = ceil(p1['hp'] / p2_actual_damage)
    return p1_rounds <= p2_rounds

input = get(21).split('\n')
enemy = {
    "hp": int(input[0].split(' ')[-1]),
    "damage": int(input[1].split(' ')[-1]),
    "armor": int(input[2].split(' ')[-1]),
}

weapons = [
    {
        "name": "Dagger",
        "cost": 8,
        "damage": 4,
        "armor": 0
    },
    {
        "name": "Shortsword",
        "cost": 10,
        "damage": 5,
        "armor": 0
Ejemplo n.º 26
0
from get_input import get
from math import prod

input = get(15).split('\n')
teaspoons = 100
properties = []
for i in input:
    i = i.split(' ')
    prop = [int(i[2][:-1]), int(i[4][:-1]), int(i[6][:-1]), int(i[8][:-1]), int(i[10])]
    properties.append(prop)

def get_score(amounts):
    tot_cap = max(0, sum([val*amount for (val, amount) in zip([p[0] for p in properties], amounts)]))
    tot_dur = max(0, sum([val*amount for (val, amount) in zip([p[1] for p in properties], amounts)]))
    tot_fla = max(0, sum([val*amount for (val, amount) in zip([p[2] for p in properties], amounts)]))
    tot_tex = max(0, sum([val*amount for (val, amount) in zip([p[3] for p in properties], amounts)]))
    tot_cal = max(0, sum([val*amount for (val, amount) in zip([p[4] for p in properties], amounts)]))
    # return prod([tot_cap, tot_dur, tot_fla, tot_tex])
    return prod([tot_cap, tot_dur, tot_fla, tot_tex]) if tot_cal == 500 else 0

highest_score = 0
for i in range(101):
    for j in range(101):
        if i+j > 100:
            break
        for k in range(101):
            if i+j+k > 100:
                break
            l = 100 - (i+j+k)
            score = get_score([i,j,k,l])
            print("{}, {}, {}, {} -> {}".format(i,j,k,l, score))
Ejemplo n.º 27
0
from get_input import get
from ctypes import c_uint16

input = get(7).split('\n')

# Maps destination wires to the gates that produce them.
wires = {}
reverse_index = {}


def reset():
    for line in input:
        line = line.split(' ')
        dest = line[-1]
        wires[dest] = [int(i) if i.isnumeric() else i for i in line[:-2]]
    for w1 in wires:
        reverse_index[w1] = []
        for w2 in wires:
            if w1 in wires[w2]:
                reverse_index[w1].append(w2)


def run(start):
    value = wires[start]
    for dest in reverse_index[start]:
        new_gate = [value if w == start else w for w in wires[dest]]
        if len(new_gate) == 2:
            wires[dest] = ~new_gate[1]
            run(dest)
        elif len(new_gate) == 3:
            [w1, op, w2] = new_gate
Ejemplo n.º 28
0
from get_input import get

input = get(3)

houses = set()
#x,y
(x,y) = (0,0)

for dir in input:
    houses.add((x,y))
    if dir == '^':
        y -= 1
    elif dir == 'v':
        y += 1
    elif dir == '>':
        x += 1
    else: # dir == '<'
        x -= 1

print(len(houses))

(santa_x, santa_y, robo_x, robo_y) = (0,0,0,0)

houses = set()


for i in range(0,len(input), 2):
    houses.add((santa_x,santa_y))
    houses.add((robo_x,robo_y))
    if input[i] == '^':
        santa_y -= 1
Ejemplo n.º 29
0
from get_input import get
from itertools import permutations

input = get(13).split('\n')


def find_highest(include_me=False):
    guests = []

    for line in input:
        line = line.split(' ')
        guests.extend([line[0], line[-1][:-1]])

    guests = sorted(list(set(guests)))
    if include_me:
        guests.append('Me')

    happiness_matrix = []
    for _ in range(len(guests)):
        happiness_matrix.append([0] * len(guests))

    for line in input:
        line = line.split(' ')
        val = int(line[3])
        if line[2] == 'lose':
            val *= -1
        i1 = guests.index(line[0])
        i2 = guests.index(line[-1][:-1])
        happiness_matrix[i1][i2] = val

    perms = [list(p) for p in permutations(range(len(guests)))]
Ejemplo n.º 30
0
from get_input import get
from math import sqrt, prod, ceil
from itertools import islice
from time import time_ns

input = int(get(20))


def divisors(x):
    n = 1
    while n <= x:
        if x % n == 0:
            yield n
        n += 1


def divisors_to(x, n):
    l = set()
    for i in range(1, n + 1):
        if x % i == 0:
            l.add(x // i)

    return list(l)


def prime_factors(x):
    if x == 1:
        yield 1
    while x % 2 == 0:
        x /= 2
        yield 2