Beispiel #1
0
Datei: day06.py Projekt: oabm/aoc
#!/usr/bin/env python3

from utils import advent
from collections import namedtuple, defaultdict

advent.setup(2018, 6)
fin = advent.get_input()

##################################################


def dist(p1, x, y):
    return abs(p1.x - x) + abs(p1.y - y)


def compute_counts(bigbound):
    counts = defaultdict(int)

    for i in range(-bigbound, bigbound):
        if i % 100 == 0:
            print(str(i) + '...')

        for j in range(-bigbound, bigbound):
            min_dist = 999999999
            nearest = None
            ignore = False

            for p in pts:
                d = dist(p, i, j)

                if d < min_dist:
Beispiel #2
0
Datei: day07.py Projekt: oabm/aoc
#!/usr/bin/env python3

from utils import advent
from collections import defaultdict, namedtuple
from string import *

advent.setup(2018, 7)
fin = advent.get_input()

##################################################

def wtf(graph, node, q, visited):
	global lol

	visited.add(node)
	# print('visited', node)

	lol += node

	for n in graph[node].next:
		q.add(n)

	while len(q):
		for n in sorted(q):
			# print('tryng', n)
			if all(x in visited for x in graph[n].need):
				# print('  need satisfied, can visit', n)

				if n not in q:
					# print('  not in queue!')
					break
Beispiel #3
0
Datei: day11.py Projekt: oabm/aoc
            for c, cell in enumerate(row):
                if cell == FLOOR:
                    continue

                occ = occ_counter(previous, r, c)

                if cell == EMPTY and occ == 0:
                    grid[r][c] = OCCUPIED
                elif cell == OCCUPIED and occ >= occ_threshold:
                    grid[r][c] = EMPTY

        if grid == previous:
            return sum(row.count(OCCUPIED) for row in grid)

        previous = grid


from utils.timer import *
advent.setup(2020, 11)
fin = advent.get_input()

original = list(map(list, map(str.rstrip, fin.readlines())))
MAXROW, MAXCOL = len(original) - 1, len(original[0]) - 1
OCCUPIED, EMPTY, FLOOR = '#L.'

total_occupied = evolve(deepcopy(original), occupied_neighbors, 4)
advent.print_answer(1, total_occupied)

total_occupied = evolve(deepcopy(original), occupied_in_sight, 5)
advent.print_answer(2, total_occupied)
Beispiel #4
0
Datei: day03.py Projekt: oabm/aoc
#!/usr/bin/env python3

from utils import advent

advent.setup(2018, 3)

fin = advent.get_input()
ans = 0
ans2 = 0

##################################################

canvas = []
for i in range(1000):
    canvas.append([])
    for j in range(1000):
        canvas[i].append({'ids': set(), 'tot': 0})

claims = {}
for line in fin:
    cid, claim = line.strip().replace(' ', '').split('@')
    cid = int(cid[1:])
    start, size = claim.split(':')
    x, y = map(int, start.split(','))
    w, h = map(int, size.split('x'))
    claims[cid] = (x, y, w, h)

for cid, c in claims.items():
    for i in range(c[0], c[0] + c[2]):
        for j in range(c[1], c[1] + c[3]):
            canvas[i][j]['tot'] += 1
Beispiel #5
0
Datei: day15.py Projekt: oabm/aoc
#!/usr/bin/env python3

from utils import advent

import sys
import copy
import networkx as nx
from sortedcontainers import SortedKeyList

advent.setup(2018, 15, True)
fin = advent.get_input()
# print(*fin)

##################################################

class Ripperoni(Exception):
	pass

def log(s, *a):
	if LOG:
		sys.stderr.write(s.format(*a))
		sys.stderr.flush()

def dump():
	log('   ' + ' '*10 + '1'*10 + '2'*10 + '3'*10 + '\n')
	log('   ' + '0123456789'*4 + '\n')

	for i, row in enumerate(cavern):
		log('{:>2d} ', i)
		for j, cell in enumerate(row):
			if (i, j) in elves:
Beispiel #6
0
Datei: day10.py Projekt: oabm/aoc
    dx, dy = bx - ax, by - ay
    div = abs(gcd(dx, dy))
    return dx // div, dy // div


def manhattan(ax, ay, bx, by):
    return abs(bx - ax) + abs(by - ay)


def angle(ax, ay, bx, by):
    rad = atan2(by - ay, bx - ax) + PI
    rad = rad % (2 * PI) - PI / 2
    return rad if rad >= 0 else 2 * PI + rad


advent.setup(2019, 10)
fin = advent.get_input()

grid = [l.rstrip() for l in fin]
asteroids = set()

for y, row in enumerate(grid):
    for x, cell in enumerate(row):
        if cell == '#':
            asteroids.add((x, y))

station = None
max_in_sight = 0

for src in asteroids:
    lines_of_sight = set()
Beispiel #7
0
    @lru_cache()
    def real_fn(i):
        if i == len(nums) - 1:
            return 1

        tot = 0
        for j in range(i + 1, min(i + 4, len(nums))):
            if nums[j] - nums[i] <= 3:
                tot += real_fn(j)

        return tot

    return real_fn(i)


advent.setup(2020, 10)
fin = advent.get_input()

nums = map(int, fin.readlines())
nums = sorted(nums)
dist1, dist3 = 1, 1

for cur, nxt in zip(nums, nums[1:]):
    delta = nxt - cur

    if delta == 1:
        dist1 += 1
    elif delta == 3:
        dist3 += 1

ans = dist1 * dist3
Beispiel #8
0
Datei: day04.py Projekt: oabm/aoc
#!/usr/bin/env python3

from utils import advent

advent.setup(2018, 4)

fin = advent.get_input()
ans = 0
ans2 = 0

arr = []
for l in fin:
    gid = -1

    if 'wakes up' in l:
        action = 'w'
    elif 'falls asleep' in l:
        action = 's'
    elif 'begins shift' in l:
        action = 'b'
        gid = l[l.find('#') + 1:]
        gid = int(gid[:gid.find(' ')])

    date, time = l[1:17].split(' ')
    y, m, d = map(int, date.split('-'))
    h, mm = map(int, time.split(':'))

    arr.append({
        'date': (y, m, d),
        'time': (h, mm),
        'action': action,
Beispiel #9
0
Datei: day16.py Projekt: oabm/aoc
#!/usr/bin/env python3

from utils import advent

advent.setup(2018, 16)
fin = advent.get_input()
# print(*fin)

##################################################


def simulate(r1, o, r2):
    op, a, b, c = o
    count = 0

    # addr
    if r2[c] == r1[a] + r1[b]: count += 1
    elif 'addr' in ops[op]: ops[op].remove('addr')

    # addi
    if r2[c] == r1[a] + b: count += 1
    elif 'addi' in ops[op]: ops[op].remove('addi')

    # mulr
    if r2[c] == r1[a] * r1[b]: count += 1
    elif 'mulr' in ops[op]: ops[op].remove('mulr')

    # muli
    if r2[c] == r1[a] * b: count += 1
    elif 'muli' in ops[op]: ops[op].remove('muli')
Beispiel #10
0
        c1, c2 = deck1.popleft(), deck2.popleft()

        if len(deck1) >= c1 and len(deck2) >= c2:
            sub1, sub2 = tuple(deck1)[:c1], tuple(deck2)[:c2]
            p1win, _ = recursive_play(deque(sub1), deque(sub2))
        else:
            p1win = c1 > c2

        if p1win:
            deck1.extend((c1, c2))
        else:
            deck2.extend((c2, c1))

    return (True, deck1) if deck1 else (False, deck2)


advent.setup(2020, 22)
fin = advent.get_input()

deck1, deck2 = map(str.splitlines, fin.read().split('\n\n'))
deck1 = deque(map(int, deck1[1:]))
deck2 = deque(map(int, deck2[1:]))

winner_deck = play(deck1.copy(), deck2.copy())
winner_score = score(winner_deck)
advent.print_answer(1, winner_score)

_, winner_deck = recursive_play(deck1, deck2)
winner_score = score(winner_deck)
advent.print_answer(2, winner_score)
Beispiel #11
0
    return set((x + dx, y + dy) for x, y in grid for dx, dy in deltas)


def evolve(grid):
    new = set()

    for p in all_neighbors(grid):
        n = black_adjacent(grid, *p)

        if n == 2 or (n == 1 and p in grid):
            new.add(p)

    return new


advent.setup(2020, 24)
fin = advent.get_input()

grid = set()  # coords of tiles with black side up
rexp = re.compile(r'e|w|se|sw|ne|nw')

for line in fin:
    moves = rexp.findall(line)
    p = walk(moves)

    if p in grid:
        grid.remove(p)
    else:
        grid.add(p)

n_black = len(grid)
Beispiel #12
0
Datei: day17.py Projekt: oabm/aoc
#!/usr/bin/env python3

from utils import advent
import re

advent.setup(2018, 17)
fin = advent.get_input()
# print(*fin)

##################################################

rexp = re.compile(r'-?\d+')
minx, miny = 9999, 9999
maxx, maxy = -9999, -9999

horizontal = []
vertical = []

for l in fin:
    a, b, c = map(int, rexp.findall(l))

    if l.startswith('x'):
        minx = min(minx, a)
        maxx = max(maxx, a)
        miny = min(miny, b)
        maxy = max(maxy, c)

        vertical.append([a, b, c])
    else:
        miny = min(miny, a)
        maxy = max(maxy, a)
Beispiel #13
0
Datei: day07.py Projekt: oabm/aoc
            visited.add(color)
            count_can_contain(G, color, visited)

    return len(visited)


@lru_cache()
def count_contained(src):
    tot = 0
    for qty, color in contains[src]:
        tot += qty * (1 + count_contained(color))

    return tot


advent.setup(2020, 7)
fin = advent.get_input()

contained_by = defaultdict(list)
contains = defaultdict(list)
inner_exp = re.compile(r'(\d+) ([\w ]+) bags?[.,]')

for line in fin:
    outer, inners = line.split(' bags contain ')
    inners = inner_exp.findall(inners)

    for qty, inner in inners:
        contained_by[inner].append(outer)
        contains[outer].append((int(qty), inner))

can_contain_gold = count_can_contain(contained_by, 'shiny gold')
Beispiel #14
0
#!/usr/bin/env python3

from utils import advent
from itertools import count

advent.setup(2020, 3)
fin = advent.get_input()

grid = [l.rstrip() for l in fin]
height, width = len(grid), len(grid[0])
trees = 0

for row, col in zip(range(height), count(0, 3)):
	if grid[row][col % width] == '#':
		trees += 1

advent.print_answer(1, trees)


total = trees

for dr, dc in ((1, 1), (1, 5), (1, 7), (2, 1)):
	trees = 0

	for row, col in zip(range(0, height, dr), count(0, dc)):
		if grid[row][col % width] == '#':
			trees += 1

	total *= trees

advent.print_answer(2, total)
Beispiel #15
0
#!/usr/bin/env python3

from utils import advent
import sys

from blist import blist

advent.setup(2018, 9)
fin = advent.get_input()

##################################################

s = fin.read().split()
nplayers, last_marble = int(s[0]), int(s[6])

marbles = blist([0])
cur_marble = 0
cur_idx = 0
cur_player = 1
scores = {}

# nplayers = 10
# last_marble = 1618

for i in range(1, nplayers + 1):
    scores[i] = 0

while cur_marble < last_marble:

    cur_marble += 1
Beispiel #16
0
Datei: day03.py Projekt: oabm/aoc
        for _ in range(n):
            p = (p[0] + MOVE_DX[d], p[1] + MOVE_DY[d])
            visited.add(p)
            cur_steps += 1

            if p not in steps:
                steps[p] = cur_steps

    return visited, steps


def manhattan(p):
    return abs(p[0]) + abs(p[1])


advent.setup(2019, 3)
lines = advent.get_input().readlines()

all_visited = []
all_steps = []

for l in lines:
    visited, steps = get_visited_and_steps(map(make_move, l.split(',')))
    all_visited.append(visited)
    all_steps.append(steps)

intersections = set.intersection(*all_visited)
min_distance = min(map(manhattan, intersections))
advent.print_answer(1, min_distance)

shortest_path = min(sum(l[p] for l in all_steps) for p in intersections)
Beispiel #17
0
Datei: day05.py Projekt: oabm/aoc
    while len(r):
        c = r.popleft()

        if c in ignore:
            continue

        if len(l) and c ^ l[-1] == 0x20:
            l.pop()
        else:
            l.append(c)

    return l


advent.setup(2018, 5)
fin = advent.get_input(mode='rb')

polymer = fin.read().rstrip()
trimmed = react_fast(polymer)
reacted_len = len(trimmed)

advent.print_answer(1, reacted_len)

best_reacted_len = reacted_len

for l, L in zip(ascii_lowercase.encode(), ascii_uppercase.encode()):
    reacted_len = len(react_fast(trimmed, {l, L}))

    if reacted_len < best_reacted_len:
        best_reacted_len = reacted_len
Beispiel #18
0
#!/usr/bin/env python3

from utils import advent

import sys
import copy

advent.setup(2018, 13)
fin = advent.get_input()
# print(*fin)

##################################################


def kill(crashxy):
    for i, cart in enumerate(carts):
        if tuple(cart[:2]) == crashxy:
            carts.pop(i)
            break


def dump(crashxy=(-1, -1)):
    cartdict = dict((tuple(c[:2]), c[2]) for c in carts)

    for i, l in enumerate(matrix):
        for j, c in enumerate(l):
            if (i, j) == crashxy:
                sys.stdout.write('X')
            elif (i, j) in cartdict:
                sys.stdout.write(cartdict[i, j])
            else:
Beispiel #19
0
Datei: day04.py Projekt: oabm/aoc
#!/usr/bin/env python3

from utils import advent
from itertools import islice

advent.setup(2019, 4)
fin = advent.get_input()

lo, hi = map(int, fin.read().split('-'))
n_valid1 = 0
n_valid2 = 0

for pwd in range(lo, hi + 1):
	digits = str(pwd)
	pairs = tuple(zip(digits, digits[1:]))

	if all(a <= b for a, b in pairs) and any(a == b for a, b in pairs):
		n_valid1 += 1

		digits = 'x' + digits + 'x'
		quadruplets = zip(digits, digits[1:], digits[2:], digits[3:])

		if any(a != b and b == c and c != d for a, b, c, d in quadruplets):
			n_valid2 += 1

advent.print_answer(1, n_valid1)
advent.print_answer(2, n_valid2)
Beispiel #20
0
Datei: day08.py Projekt: oabm/aoc
#!/usr/bin/env python3

from utils import advent

advent.setup(2018, 8)
fin = advent.get_input()

##################################################

def scan(n, cur_id):
	nchilds = n[0]
	nmeta = n[1]

	if nchilds == 0:
		tree[cur_id] = ([], n[2:2+nmeta])
		return sum(tree[cur_id][1]), 2 + nmeta

	cur_len = 2
	meta_sum = 0
	childs = []

	for _ in range(nchilds):
		child_id = cur_id + cur_len
		childs.append(child_id)

		child_meta_sum, child_len = scan(n[cur_len:], child_id)
		meta_sum += child_meta_sum
		cur_len += child_len

	tree[cur_id] = (childs, n[cur_len:cur_len+nmeta])
Beispiel #21
0
Datei: day01.py Projekt: oabm/aoc
#!/usr/bin/env python3

from utils import advent

advent.setup(2019, 1)
fin = advent.get_input()

nums = map(int, fin.readlines())
nums = tuple(map(lambda n: n // 3 - 2, nums))
total = sum(nums)

advent.print_answer(1, total)

for n in nums:
	while n > 0:
		n = max(n // 3 - 2, 0)
		total += n

advent.print_answer(2, total)
Beispiel #22
0
Datei: day16.py Projekt: oabm/aoc
    assigned = [None] * len(possible)

    while any(possible):
        for i, poss in enumerate(possible):
            if len(poss) == 1:
                assigned[i] = match = poss.pop()
                break

        for other in possible:
            if match in other:
                other.remove(match)

    return assigned


advent.setup(2020, 16)
fin = advent.get_input()

ranges, my_ticket, tickets = parse_input(fin)
total = sum(map(sum, map(invalid_fields, tickets)))

advent.print_answer(1, total)

tickets.append(my_ticket)
n_fields = len(my_ticket)
possible = [set(range(n_fields)) for _ in range(len(ranges))]

for ticket in filter(is_valid, tickets):
    for rng, poss in zip(ranges, possible):
        for i, value in enumerate(ticket):
            if value not in rng and i in poss:
Beispiel #23
0
Datei: day12.py Projekt: oabm/aoc
    SOUTH: lambda x, y, n: (x, y - n),
    EAST: lambda x, y, n: (x + n, y),
    WEST: lambda x, y, n: (x - n, y)
}

# Function to apply to rotate around the origin.
ROTMAP = {
    (LEFT, 90): lambda x, y: (-y, x),
    (LEFT, 180): lambda x, y: (-x, -y),
    (LEFT, 270): lambda x, y: (y, -x),
    (RIGHT, 90): lambda x, y: (y, -x),
    (RIGHT, 180): lambda x, y: (-x, -y),
    (RIGHT, 270): lambda x, y: (-y, x),
}

advent.setup(2020, 12)
fin = advent.get_input()

commands = tuple(map(lambda l: (l[0], int(l[1:])), fin))

x, y = 0, 0
dx, dy = 1, 0  # start facing EAST

for cmd, n in commands:
    if cmd == 'F':
        x += dx * n
        y += dy * n
    elif cmd in 'LR':
        dx, dy = ROTMAP[cmd, n](dx, dy)
    else:
        x, y = MOVEMAP[cmd](x, y, n)
Beispiel #24
0
Datei: day20.py Projekt: oabm/aoc
    for img in arrangements(image):
        n = 0
        for r in range(image_sz - pattern_h):
            for c in range(image_sz - pattern_w):
                if all(img[r + dr][c + dc] == '#' for dr, dc in deltas):
                    n += 1

        if n != 0:
            return n


MONSTER_PATTERN = ('                  # ', '#    ##    ##    ###',
                   ' #  #  #  #  #  #   ')

advent.setup(2020, 20)
fin = advent.get_input()

tiles = parse_input(fin)
corners = match_tiles(tiles)
ans = prod(corners)

advent.print_answer(1, ans)

top_left_id, matching_sides = corners.popitem()
top_left = tiles[top_left_id]

if matching_sides in ('ne', 'en'):
    top_left = rotate90(top_left)
elif matching_sides in ('nw', 'wn'):
    top_left = rotate90(rotate90(top_left))
Beispiel #25
0
    while hi - lo > 1:
        x = (lo + hi) // 2

        width, y = get_width(x, target)

        if width > target:
            hi = x
            best = (x, y)
        elif width < target:
            lo = x

    return best


advent.setup(2019, 19)
fin = advent.get_input()

program = list(map(int, fin.read().split(',')))
total = sum(map(run, product(range(50), range(50))))

advent.print_answer(1, total)

TARGET = 100
bestx, besty = bin_search(10, 9999, TARGET)

for x in range(bestx, bestx - 10, -1):
    width, y = get_width(x, TARGET)

    if width >= TARGET:
        bestx, besty = x, y
Beispiel #26
0
Datei: day18.py Projekt: oabm/aoc
        if tok.isdigit():
            val = int(tok) * multiplier
            accumulator = op(accumulator, val)
        elif tok == '+':
            op = add
        elif tok == '*':
            if plus_precedence:
                multiplier = accumulator
                accumulator = 0
            else:
                op = mul
        elif tok == '(':
            val = evaluate(tokens, plus_precedence) * multiplier
            accumulator = op(accumulator, val)
        else:  # ')'
            break

    return accumulator


advent.setup(2020, 18)
fin = advent.get_input()

exprs = tuple(map(tokenize, fin))
total = sum(map(evaluate, map(deque, exprs)))
advent.print_answer(1, total)

total = sum(map(partial(evaluate, plus_precedence=True), map(deque, exprs)))
advent.print_answer(2, total)
Beispiel #27
0
#!/usr/bin/env python3

from utils import advent

advent.setup(2018, 11)
fin = advent.get_input()

##################################################


def fuel(x, y):
    rid = x + 10
    powlevel = ((((rid * y + serial_no) * rid) // 100) % 10) - 5
    return powlevel


def get_power(xy, m=3):
    s = 0
    x, y = xy
    for j in range(y, y + m):
        for i in range(x, x + m):
            s += grid[j][i]
    return s


serial_no = int(fin.read())

grid = []
for j in range(300 + 1):
    grid.append([])
    for i in range(300 + 1):
Beispiel #28
0
Datei: day15.py Projekt: oabm/aoc
def bfs_farthest(maze, src):
    visited = set()
    queue = deque([(0, src)])

    while queue:
        dist, node = queue.popleft()

        if node not in visited:
            visited.add(node)

            for n in filter(lambda n: n not in visited,
                            neighbors4(maze, *node)):
                queue.append((dist + 1, n))

    return dist


advent.setup(2019, 15)
fin = advent.get_input()

program = list(map(int, fin.read().split(',')))
vm = IntcodeVM(program)

startpos = (0, 0)
maze, oxygen = wall_follower(vm, startpos)
min_dist = bfs_shortest(maze, startpos, oxygen)
advent.print_answer(1, min_dist)

time = bfs_farthest(maze, oxygen)
advent.print_answer(2, time)
Beispiel #29
0
Datei: day21.py Projekt: oabm/aoc
        for ingr, possible in possible_allers.items():
            if len(possible) == 1:
                break

        aller = possible.pop()
        assigned[aller] = ingr
        del possible_allers[ingr]

        for ingr, possible in possible_allers.items():
            if aller in possible:
                possible.remove(aller)

    return assigned


advent.setup(2020, 21)
fin = advent.get_input()

recipes, possible_allers, recipes_with = parse_input(fin)

safe = safe_ingredients(recipes, possible_allers, recipes_with)
tot = sum(ingr in r for r in recipes for ingr in safe)

advent.print_answer(1, tot)

for ingr in safe:
    del possible_allers[ingr]

assigned = simplify(possible_allers)
lst = ','.join(map(assigned.get, sorted(assigned)))
Beispiel #30
0
#!/usr/bin/env python3

from utils import advent
from functools import reduce, partial

advent.setup(2020, 6)
fin = advent.get_input()

into_sets = partial(map, set)
unionize = partial(reduce, set.union)
intersect = partial(reduce, set.intersection)

raw_groups = fin.read().split('\n\n')
groups = tuple(map(tuple, map(into_sets, map(str.splitlines, raw_groups))))

n_any_yes = sum(map(len, map(unionize, groups)))
n_all_yes = sum(map(len, map(intersect, groups)))

advent.print_answer(1, n_any_yes)
advent.print_answer(2, n_all_yes)