#!/usr/bin/python3.8 from aoc import Env from collections import defaultdict e = Env(24) e.T( """sesenwnenenewseeswwswswwnenewsewsw neeenesenwnwwswnenewnwwsewnenwseswesw seswneswswsenwwnwse nwnwneseeswswnenewneswwnewseswneseene swweswneswnenwsewnwneneseenw eesenwseswswnenwswnwnwsewwnwsene sewnenenenesenwsewnenwwwse wenwwweseeeweswwwnwwe wsweesenenewnwwnwsenewsenwwsesesenwne neeswseenwwswnwswswnw nenwswwsewswnenenewsenwsenwnesesenew enewnwewneswsewnwswenweswnenwsenwsw sweneswneswneneenwnewenewwneswswnese swwesenesewenwneswnwwneseswwne enesenwswwswneneswsenwnewswseenwsese wnwnesenesenenwwnenwsewesewsesesew nenewswnwewswnenesenwnesewesw eneswnwswnwsenenwnwnwwseeswneewsenese neswnwewnwnwseenwseesewsenwsweewe wseweeenwnesenwwwswnew""", 10, 2208) move = { 'se': (1, 1), 'sw': (1, -1),
#!/usr/bin/python3.8 from aoc import Env from collections import deque import re e = Env(14) e.T( """mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X mem[8] = 11 mem[7] = 101 mem[8] = 0""", 165, None) e.T( """mask = 000000000000000000000000000000X1001X mem[42] = 100 mask = 00000000000000000000000000000000X0XX mem[26] = 1""", None, 208) def parse_mask(maskstr): o = {} for i, c in enumerate(maskstr[::-1]): if c in '01': o[i] = int(c) return o def apply_mask(mask, val): for p, v in mask.items(): if v == 1:
#!/usr/bin/python3.8 from aoc import Env, Modular e = Env(13) e.T("""939 7,13,x,x,59,x,31,19""", 295, 1068781) e.T("""0 17,x,13,19""", None, 3417) e.T("""0 67,7,59,61""", None, 754018) e.T("""0 67,x,7,59,61""", None, 779210) e.T("""0 67,7,x,59,61""", None, 1261476) e.T("""0 1789,37,47,1889""", None, 1202161486) e.T("""0 3,5""", None, 9) def parse_input(inp): ln = inp.get_valid_lines() timestamp = int(ln[0]) buses = [(int(bn), i) for i, bn in enumerate(ln[1].split(',')) if bn != 'x'] return timestamp, buses def part1(input): timestamp, buses = parse_input(input)
#!/usr/bin/env python3 from aoc import Env import re e = Env(4) e.T( """[1518-11-01 00:00] Guard #10 begins shift [1518-11-01 00:05] falls asleep [1518-11-01 00:25] wakes up [1518-11-01 00:30] falls asleep [1518-11-01 00:55] wakes up [1518-11-01 23:58] Guard #99 begins shift [1518-11-02 00:40] falls asleep [1518-11-02 00:50] wakes up [1518-11-03 00:05] Guard #10 begins shift [1518-11-03 00:24] falls asleep [1518-11-03 00:29] wakes up [1518-11-04 00:02] Guard #99 begins shift [1518-11-04 00:36] falls asleep [1518-11-04 00:46] wakes up [1518-11-05 00:03] Guard #99 begins shift [1518-11-05 00:45] falls asleep [1518-11-05 00:55] wakes up""", 240, 4455) def parse_event(event): m = re.match(r'^\[1518-(\d\d)-(\d\d) (\d\d):(\d\d)\] (.*)', event) assert m is not None, f"Cannot parse line {event}" _d, _m, _h, _mm, what = m.groups() # day = int(_d)
#!/usr/bin/python3.8 # Note: https://oeis.org/A181391 from aoc import Env import numpy e = Env(15) e.T("0,3,6", 436, 175594) def van_eck(start, K): memory = numpy.zeros(K, dtype=int) for i, x in enumerate(start): memory[x] = i + 1 last_said = 0 # Assuming all numbers in start are unique next = 0 turn = len(start) + 1 while turn <= K: # elf says next last_said = next # when was that said last time next = memory[last_said] if next != 0: next = turn - next memory[last_said] = turn turn += 1
#!/usr/bin/python3.8 from aoc import Env from collections import defaultdict import re e = Env(16) e.T("""departure class: 1-3 or 5-7 departure row: 6-11 or 33-44 seat: 13-40 or 45-50 your ticket: 7,1,14 nearby tickets: 7,3,47 40,4,50 55,2,20 38,6,12 """, 71, 1*7) e.T("""departure class: 0-1 or 4-19 departure row: 0-5 or 8-19 seat: 0-13 or 16-19 your ticket: 11,12,13 nearby tickets: 3,9,18 15,1,5 5,14,9
#!/usr/bin/python3.8 from aoc import Env from collections import deque import re e = Env(19) e.T( """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 """, 2, None) e.T( """42: 9 14 | 10 1 9: 14 27 | 1 26 10: 23 14 | 28 1 1: "a" 11: 42 31 5: 1 14 | 15 1 19: 14 1 | 14 14 12: 24 14 | 19 1 16: 15 1 | 14 14
#!/usr/bin/python3.8 from aoc import Env from collections import Counter e = Env(2) e.T("""abcdef bababc abbcde abcccd aabcdd abcdee ababab""", 12, None) e.T("""abcde fghij klmno pqrst fguij axcye wvxyz""", None, 'fgij') def part1(input): ids = input.get_valid_lines() twos = 0 threes = 0 for id in ids: counts = Counter(id) if 2 in counts.values(): twos += 1 if 3 in counts.values():
#!/usr/bin/python3.8 from aoc import Env from collections import deque e = Env(22) e.T("""Player 1: 9 2 6 3 1 Player 2: 5 8 4 7 10 """, 306, 291) def play(decks): rounds = 0 while True: if not decks[0] or not decks[1]: return rounds draw = [decks[0].popleft(), decks[1].popleft()] if draw[0] > draw[1]: decks[0].append(draw[0]) decks[0].append(draw[1])
#!/usr/bin/python3.8 from aoc import Env, Grid from collections import defaultdict e = Env(17) e.T(""".#. ..# ###""", 112, 848) def make_grid(input): ingrid = Grid(input.get_valid_lines()) grid = defaultdict(bool) for row in range(ingrid.h): for col in range(ingrid.w): if ingrid.grid[row][col] == '#': grid[(col, row, 0)] = True return grid, ((0, ingrid.w), (0, ingrid.h), (0, 1)) def count_neighbors(x, y, z, grid): count = 0 for a in [-1, 0, 1]: for b in [-1, 0, 1]: for c in [-1, 0, 1]: if a == 0 and b == 0 and c == 0: continue if (x + a, y + b, z + c) in grid: count += 1 return count
#!/usr/bin/python3.8 from aoc import Env from collections import defaultdict from functools import reduce import math import re e = Env(20) e.T("""Tile 2311: ..##.#..#. ##..#..... #...##..#. ####.#...# ##.##.###. ##...#.### .#.#.#..## ..#....#.. ###...#.#. ..###..### Tile 1951: #.##...##. #.####...# .....#..## #...###### .##.#....# .###.##### ###.##.##. .###....#. ..#.#..#.#
#!/usr/bin/python3.8 from aoc import Env e = Env(25) e.T("""5764801 17807724""", 14897079, None) def get_loop_number(key): v = 1 for i in range(20201227): v = (v * 7) % 20201227 if v == key: return i + 1 assert False def loop(start, loops): v = 1 for _ in range(loops): v = (v * start) % 20201227 return v def part1(input): ln = input.get_valid_lines() A = int(ln[0]) B = int(ln[1]) # A = 7 ** n mod 20201227 # B = 7 ** m mod 20201227
#!/usr/bin/python3.8 from aoc import Env from collections import defaultdict from functools import reduce import math import re import random e = Env(20) monster = [ "..................#.", "#....##....##....###", ".#..#..#..#..#..#...", ] frame_counter = 0 frame = [] for r in range(12 * 10): frame += [[' '] * 12 * 10] palette = { ' ': '000000', # blank space '.': '99d9ea', # water - low '#': '00a2e8', # water - high '-': 'ff7da8', # picture border - low '@': 'ff3778', # picture border - high ';': '9e9e9e', # tile edge - low '*': '434343', # tile edge - high
#!/usr/bin/python3.8 from aoc import Env from collections import namedtuple, defaultdict import re e = Env(3) e.T("""#1 @ 1,3: 4x4 #2 @ 3,1: 4x4 #3 @ 5,5: 2x2""", 4, 3) Claim = namedtuple('Claim', ['id', 'left', 'top', 'width', 'height']) def parse_input(input): claims = [] for ln in input.get_valid_lines(): m = re.search(r'^#(\d+) @ (\d+),(\d+): (\d+)x(\d+)', ln) assert m is not None id, left, top, wid, hei = [int(m.group(i)) for i in range(1, 6)] claims += [Claim(id=id, left=left, top=top, width=wid, height=hei)] return claims def draw_claims(claims): fabric = defaultdict(int) for claim in claims: for x in range(claim.left, claim.left + claim.width): for y in range(claim.top, claim.top + claim.height): fabric[(x, y)] += 1
#!/usr/bin/python3.8 from aoc import Env import re e = Env(18) e.T("1 + 2 * 3 + 4 * 5 + 6", 71, 231) e.T("1 + (2 * 3) + (4 * (5 + 6))", 51, 51) e.T("2 * 3 + (4 * 5)", None, 46) e.T("5 + (8 * 3 + 9 + 3 * 4 * 3)", None, 1445) e.T("5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))", None, 669060) e.T("((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2", None, 23340) def evaluate_expr(ln): tokens = re.findall(r'(\d+|\+|\*|\(|\))', ln) stack = [] for tok in tokens: if tok in '(+*': stack.append(tok) continue elif tok == ')': # assuming that parentheses are never empty val = stack.pop() _ = stack.pop() else: val = int(tok) if not stack or stack[-1] == '(': stack.append(val) else:
#!/usr/bin/python3.8 from aoc import Env e = Env(1) e.T("""+1 +1 +1""", 3, None) e.T("""+1 +1 -2""", 0, None) e.T("""-1 -2 -3""", -6, None) e.T("""+1 -2 +3 +1""", None, 2) def part1(input): ints = [int(x) for x in input.get_valid_lines()] return sum(ints) e.run_tests(1, part1) e.run_main(1, part1) def part2(input): ints = [int(x) for x in input.get_valid_lines()]
#!/usr/bin/python3.8 from aoc import Env e = Env(23) e.T("389125467", 67384529, 149245887792) class Node: def __init__(self, val): self.val = val self.prev = None self.next = None def make_nodes(start, add_to_million): for v in start: yield Node(v) if add_to_million: for i in range(max(start) + 1, 1_000_001): yield Node(i) def make_move(current, nodemap): maxnum = len(nodemap) current_node = nodemap[current] taken = [ current_node.next, current_node.next.next, current_node.next.next.next ] taken_vals = [x.val for x in taken] current_node.next = current_node.next.next.next.next