def test_setattr_doesnt_submit_if_already_done(mocker, aocd_dir): answer_path = aocd_dir / "thetesttoken" / "2017_07a_answer.txt" answer_path.write_text("someval") puzzle = Puzzle(year=2017, day=7) mock = mocker.patch("aocd.models.Puzzle._submit") puzzle.answer_a = "someval" mock.assert_not_called()
def solve_puzzle(soln, a_or_b): puzzle = Puzzle(year=2018, day=2) answer = soln(puzzle.input_data) if a_or_b == "a": puzzle.answer_a = answer else: puzzle.answer_b = answer
def solve_puzzle(soln, a_or_b): puzzle = Puzzle(year=2020, day=1) answer = soln(puzzle.input_data) print(answer) if a_or_b == "a": puzzle.answer_a = answer else: puzzle.answer_b = answer
depth = 0 dist = 0 aim = 0 for command, num in pairs: if command == 'down': aim += num elif command == 'up': aim -= num elif command == 'forward': dist += num depth += num * aim else: raise Exception(f"oops {command=}, {num=}") return depth * dist if __name__ == "__main__": puzzle = Puzzle(year=2021, day=2) pairs = list( map(lambda pair: (pair[0], int(pair[1])), map(lambda x: x.split(), puzzle.input_data.split('\n')))) solution_a = solve_a(pairs) print(f"Part A: {solution_a}") puzzle.answer_a = solution_a solution_b = solve_b(pairs) print(f"Part B: {solution_b}") puzzle.answer_b = solution_b
key=lambda i: (i == 0).sum()) part_a = int((min_layer == 2).sum() * (min_layer == 1).sum()) image = np.full(layer_shape, TRANSPARENT, dtype=int) for layer in iter_layers(data, layer_shape): mask = image == TRANSPARENT image[mask] = layer[mask] render = '\n'.join(''.join('#' if item == WHITE else ' ' for item in row) for row in image) return part_a, ocr(render) def iter_layers(data, shape): rows, cols = shape for layer in grouper(data, rows * cols): yield np.array([int(c) for c in layer]).reshape(*shape) if __name__ == '__main__': from aocd.models import Puzzle puz = Puzzle(2019, 8) part_a, part_b = run(puz.input_data) puz.answer_a = part_a print(f'Part 1: {puz.answer_a}') puz.answer_b = part_b print(f'Part 2: {puz.answer_b}')
o.step() step_count += 1 return step_count if __name__ == "__main__": from aocd.models import Puzzle test_data = """5483143223 2745854711 5264556173 6141336146 6357385478 4167524645 2176841721 6882881134 4846848554 5283751526""" assert solve1(test_data) == 1656 assert solve2(test_data) == 195 puzzle = Puzzle(2021, 11) answer_1 = solve1(puzzle.input_data) print(answer_1) puzzle.answer_a = answer_1 answer_2 = solve2(puzzle.input_data) print(answer_2) puzzle.answer_b = answer_2
from aocd.models import Puzzle from robot import Robot puzzle = Puzzle(year=2019, day=11) data = puzzle.input_data.split("\n") result = 0 prog = [int(x) for x in puzzle.input_data.split(",")] + [0 for i in range(0, 6000)] rur = Robot(prog) rur.run() result = rur.paintCount print("2019-Day11-A result:", result) puzzle.answer_a = result
[0, 1, 1, 2, 1, 1, 1, 2, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [2, 2, 2, 1, 1, 1, 0, 0, 0, 0], ] assert count_overlaps(grid) == 5 puz = Puzzle(2021, 5) data = process_input(puz.input_data) grid = build_grid(data) puz.answer_a = count_overlaps(grid) print(f"Part 1: {puz.answer_a}") grid = build_grid(test_vals, True) assert grid.tolist() == [ [1, 0, 1, 0, 0, 0, 0, 1, 1, 0], [0, 1, 1, 1, 0, 0, 0, 2, 0, 0], [0, 0, 2, 0, 1, 0, 1, 1, 1, 0], [0, 0, 0, 1, 0, 2, 0, 2, 0, 0], [0, 1, 1, 2, 3, 1, 3, 2, 1, 1], [0, 0, 0, 1, 0, 2, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 1, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0], [2, 2, 2, 1, 1, 1, 0, 0, 0, 0], ]
if __name__ == "__main__": from aocd.models import Puzzle test_vals = process_input("""939 7,13,x,x,59,x,31,19""") test_timestamp, test_bus = find_earliest_bus(*test_vals) assert test_timestamp == 944 assert test_bus == 59 assert (test_timestamp - test_vals[0]) * test_bus == 295 puz = Puzzle(2020, 13) data = process_input(puz.input_data) timestamp, bus = find_earliest_bus(*data) puz.answer_a = (timestamp - data[0]) * bus print(f"Part 1: {puz.answer_a}") assert find_smallest_bus_timestamp([17, float("inf"), 13, 19]) == 3417 assert find_smallest_bus_timestamp([67, 7, 59, 61]) == 754018 assert find_smallest_bus_timestamp([67, float("inf"), 7, 59, 61]) == 779210 assert find_smallest_bus_timestamp([67, 7, float("inf"), 59, 61]) == 1261476 assert find_smallest_bus_timestamp([1789, 37, 47, 1889]) == 1202161486 assert find_sequential_bus_timestamp([17, float("inf"), 13, 19]) == 3417 assert find_sequential_bus_timestamp([67, 7, 59, 61]) == 754018 assert find_sequential_bus_timestamp([67, float("inf"), 7, 59, 61]) == 779210 assert find_sequential_bus_timestamp([67, 7, float("inf"), 59, 61]) == 1261476
if __name__ == '__main__': from aocd.models import Puzzle code = '''cpy 2 a tgl a tgl a tgl a cpy 1 a dec a dec a''' insts = list(assemble(code)) assert run(insts) == 3 puz = Puzzle(2016, 23) insts = list(assemble(puz.input_data)) puz.answer_a = run(insts, a=7) print('Part 1:', puz.answer_a) # Hack code to replace nested loops with multiplications insts = list(assemble(puz.input_data)) insts[17][1] = -8 insts[3:10] = [['cpy', 'b', 'a'], ['mul', 'd', 'a']] insts[7:11] = [['mul', 2, 'c']] puz.answer_b = run(insts, a=12) print('Part 2:', puz.answer_b)
from blist import blist from aocd import get_data from functools import reduce from aocd.models import Puzzle import math puzzle = Puzzle(year=2019, day=16) raw = puzzle.input_data data = [ int(i) for i in raw ] d = np.array(data,dtype=int) base_patt = [0,1,0,-1] for _ in range(100): d_new = np.copy(d) for i in range(len(d)): pi = np.repeat(base_patt,i+1) pi_tile = np.tile(pi, math.ceil(len(d)/(len(pi)-1))) d_new[i] = abs(d.dot(pi_tile[1:len(d)+1]))%10 d = d_new puzzle.answer_a = ''.join([str(i) for i in d[:8]]) d_new = data*10000 offset = int(''.join(map(str, d_new[:7]))) relevant = d_new[offset:] for _ in range(100): for i in range(-2,-len(relevant)-1, -1): relevant[i] = (relevant[i]+relevant[i+1])%10 puzzle.answer_b = ''.join([str(i) for i in relevant[:8]])
moves = { 'se': -1 + 1j, 'ne': 1 + 1j, 'nw': 1 - 1j, 'sw': -1 - 1j, 'e': 2j, 'w': -2j } for _ in range(ndays): for k, v in tiles.items(): adjB = sum(1 for i in moves.values() if k + i in tiles and tiles[k + i] == 'B') if v == 'B': new_tiles[k] = 'W' if adjB == 0 or adjB > 2 else 'B' else: new_tiles[k] = 'B' if adjB == 2 else 'W' for i in moves.values(): kk = k + i if kk not in tiles: adjB = sum(1 for j in moves.values() if kk + j in tiles and tiles[kk + j] == 'B') new_tiles[kk] = 'B' if adjB == 2 else 'W' new_tiles, tiles = tiles, new_tiles return sum(1 for i in tiles.values() if i == 'B') PUZZLE = Puzzle(year=2020, day=24) INPUT = PUZZLE.input_data PUZZLE.answer_a, tiles = part1(INPUT) PUZZLE.answer_b = part2(tiles, 100)
import string import re def group_answers1_iter(groups): for group in groups: group_ = ''.join(set(group.replace('\n', ''))) yield len(group_) def part1(groups): return sum(group_answers1_iter(groups)) def group_answers2_iter(groups): for group in groups: people = [set(person) for person in group.splitlines()] intersection = set.intersection(*people) yield len(intersection) def part2(groups): return sum(group_answers2_iter(groups)) PUZZLE = Puzzle(year=2020, day=6) INPUT = PUZZLE.input_data groups = INPUT.split('\n\n') PUZZLE.answer_a = part1(groups) PUZZLE.answer_b = part2(groups)
assert check_line('[{[{({}]{}}([{[{{{}}([]') == (False, ']') assert check_line('[<(<(<(<{}))><([]([]()') == (False, ')') assert check_line('<{([([[(<>()){}]>(<<{{') == (False, '>') assert check_line('[({(<(())[]>[[{[]{<()<>>') == (True, '}}]])})]') assert check_line('[(()[<>])]({[<{<<[]>>(') == (True, ')}>]})') assert check_line('(((({<>}<{<{<>}{[]{[]{}') == (True, '}}>}>))))') assert check_line('{<[[]]>}<{[{[{[]{()[[[]') == (True, ']]}}]}]}>') assert check_line('<{([{{}}[<[[[<>{}]]]>[]]') == (True, '])}>') sample = '''[({(<(())[]>[[{[]{<()<>> [(()[<>])]({[<{<<[]>>( {([(<{}[<>[]}>{[]{[(<()> (((({<>}<{<{<>}{[]{[]{} [[<[([]))<([[{}[[()]]] [{[{({}]{}}([{[{{{}}([] {<[[]]>}<{[{[{[]{()[[[] [<(<(<(<{}))><([]([]() <{([([[(<>()){}]>(<<{{ <{([{{}}[<[[[<>{}]]]>[]]''' assert check_code(sample) == (26397, 288957) puz = Puzzle(2021, 10) syntax, completion = check_code(puz.input_data) puz.answer_a = syntax print(f'Part 1: {puz.answer_a}') puz.answer_b = completion print(f'Part 2: {puz.answer_b}')
elif op == 'jnz': if regs.get(t1, t1): ptr += t2 continue elif op == 'cpy': regs[t2] = regs.get(t1, t1) ptr += 1 return regs['a'] if __name__ == '__main__': from aocd.models import Puzzle code = '''cpy 41 a cpy a b jnz 1 1 inc a inc a dec a jnz a 2 dec a''' assert run(code) == 42 puz = Puzzle(2016, 12) puz.answer_a = run(puz.input_data) print('Part 1:', puz.answer_a) puz.answer_b = run(puz.input_data, c=1) print('Part 2:', puz.answer_b)
s = r'''/->-\ | | /----\ | /-+--+-\ | | | | | v | \-+-/ \-+--/ \------/''' network, carts = parse(s) crash = run(network, carts) assert crash == (7, 3) f2 = r'''/>-<\ | | | /<+-\ | | | v \>+</ | | ^ \<->/''' network, carts = parse(f2) assert crash_all(network, carts) == (6, 4) puz = Puzzle(2018, 13) network, carts = parse(puz.input_data) puz.answer_a = ','.join(str(i) for i in run(network, carts)) print(f'Part 1: {puz.answer_a}') network, carts = parse(puz.input_data) puz.answer_b = ','.join(str(i) for i in crash_all(network, carts)) print(f'Part 2: {puz.answer_b}')
for parent, child in orbits: dag[parent].append(child) return dag dag = build_dag(data) seen = set() def orbit_count(node, depth): if (node in seen): return 0 seen.add(node) return depth + sum(orbit_count(child, depth + 1) for child in dag[node]) puzzle.answer_a = (orbit_count('COM', 0)) def build_graph(orbits): graph = defaultdict(list) for parent, child in orbits: graph[parent].append(child) graph[child].append(parent) return graph graph = build_graph(data) seen = set() def calc_transfers(start, end, counter):
r.append(''.join(i)) return r rule42 = extract_rule('42', RULES) rule31 = extract_rule('31', RULES) lenrule = len(rule42[0]) count = 0 for m in MSGS.splitlines(): if len(m) % lenrule != 0: continue n_chunks = len(m) // lenrule chunks = [m[i:i + lenrule] for i in range(0, len(m), lenrule)] f = 1 while n_chunks - 2 * f > 0: i = n_chunks - f if all(c in rule42 for c in chunks[:i]) and all(c in rule31 for c in chunks[i:]): count += 1 break f += 1 print(count) PUZZLE = Puzzle(year=2020, day=19) INPUT = PUZZLE.input_data RULES, MSGS = INPUT.split('\n\n') RULES = parse_rules(RULES) PUZZLE.answer_a = part1('0', MSGS, RULES) PUZZLE.answer_b = part2('0', MSGS, RULES)
def supports_ssl(ip): blocks, hypernets = parse_ip(ip) babs = set(bab for b in hypernets for bab in find_abas(b)) return any(aba_to_bab(aba) in babs for b in blocks for aba in find_abas(b)) if __name__ == '__main__': from aocd.models import Puzzle assert supports_tls('abba[mnop]qrst') assert supports_tls('abcd[bdab]xyyx') assert not supports_tls('abcd[bddb]xyyx') assert not supports_tls('aaaa[qwer]tyui') assert supports_tls('ioxxoj[asdfgh]zxcvbn') assert supports_ssl('aba[bab]xyz') assert not supports_ssl('xyx[xyx]xyx') assert supports_ssl('aaa[kek]eke') assert supports_ssl('zazbz[bzb]cdb') puz = Puzzle(2016, 7) puz.answer_a = sum(supports_tls(ip) for ip in puz.input_data.split('\n')) print('Part 1:', puz.answer_a) puz.answer_b = sum(supports_ssl(ip) for ip in puz.input_data.split('\n')) print('Part 2:', puz.answer_b)
] return ''.join(map(str, digits[:8])) def part2(number, phases=100): """ >>> part2('03036732577212944063491565474664') '84462026' >>> part2('02935109699940807407585447034323') '78725270' >>> part2('03081770884921959731165446850517') '53553731' """ offset = int(number[:7]) digits = [int(digit) for digit in number] * 10000 digits = reversed(digits[offset:]) for _ in range(phases): digits = [value % 10 for value in accumulate(digits, func=add)] return ''.join(map(str, reversed(digits[-8:]))) if __name__ == "__main__": import doctest doctest.testmod() print("Tests complete!") puzzle = Puzzle(year=2019, day=16) number = puzzle.input_data puzzle.answer_a = inspect(part1(number), prefix='Part 1: ') puzzle.answer_b = inspect(part2(number), prefix='Part 2: ')
return table def routes(table): for route in itertools.permutations( {*(k[0] for k in table), *(k[1] for k in table)}): yield sum( table.get((start, end), table.get((end, start))) for start, end in zip(route[1:], route[:-1])) if __name__ == '__main__': from aocd.models import Puzzle t = r'''London to Dublin = 464 London to Belfast = 518 Dublin to Belfast = 141''' table = parse(t) assert min(routes(table)) == 605 assert max(routes(table)) == 982 puz = Puzzle(2015, 9) table = parse(puz.input_data) puz.answer_a = min(routes(table)) print(f'Part 1: {puz.answer_a}') puz.answer_b = max(routes(table)) print(f'Part 2: {puz.answer_b}')
cache_key = f"{current} {repr(keys)}" if cache_key in cache: return cache[cache_key] result = float('inf') for key, dist in reachable(current, keys): new_dist = dist + distance_to_collect(all_keys[key], keys - {key}) result = min(result, new_dist) cache[cache_key] = result return result return distance_to_collect(start, set(all_keys.keys())) # def part2(lines): # """ # >>> part2() # # """ if __name__ == "__main__": import doctest doctest.testmod() puzzle = Puzzle(year=2019, day=18) lines = puzzle.input_data.split('\n') puzzle.answer_a = inspect(part1(lines), prefix='Part 1: ') # puzzle.answer_b = inspect(part2(lines), prefix='Part 2: ')
return len(paint(program, start=0)) def part2(program): hull = paint(program, start=1) minx_coord = min(c.x for c in hull.keys()) miny_coord = min(c.y for c in hull.keys()) maxx_coord = max(c.x for c in hull.keys()) maxy_coord = max(c.y for c in hull.keys()) visualisation = [] for y in range(maxy_coord, miny_coord - 1, -1): row = [] for x in range(minx_coord, maxx_coord + 1): if hull[Coord(x, y)] == 1: row.append('█') else: row.append(' ') visualisation.append(''.join(row)) return input('Hull:\n' + '\n'.join(visualisation)) if __name__ == "__main__": import doctest doctest.testmod() puzzle = Puzzle(year=2019, day=11) program = [int(val) for val in puzzle.input_data.split(',')] puzzle.answer_a = inspect(part1(program), prefix='Part 1: ') puzzle.answer_b = inspect(part2(program), prefix='Part 2: ')
max_x = max(painted)[0] min_x = min(painted)[0] nx = max_x - min_x + 1 max_y = max(painted, key = lambda p : p[1])[1] min_y = min(painted, key = lambda p : p[1])[1] ny = max_y - min_y + 1 reg = [ [' ']*nx for _ in range(ny)] for y in range(ny): for x in range(nx): if grid[(x+min_x,y+min_y)] == 2: reg[y][x] = '*' elif grid[(x+min_x,y+min_y)] == 1: reg[y][x] = '|' elif grid[(x+min_x,y+min_y)] == 3: reg[y][x] = '_' elif grid[(x+min_x,y+min_y)] == 4: reg[y][x] = '@' for i in range(ny): print(''.join(reg[i])) program = intcode.Intcode(data) grid = run_arcade(program) counts = Counter(grid.values()) puzzle.answer_a = counts[2] program = intcode.Intcode(data) program.set(0, 2) grid = run_arcade(program) puzzle.answer_b = grid[(-1,0)]
assert str(test) == '''###.... ###.... .......''' test('rotate column x=1 by 1') assert str(test) == '''#.#.... ###.... .#.....''' test('rotate row y=0 by 4') assert str(test) == '''....#.# ###.... .#.....''' test('rotate column x=1 by 1') assert str(test) == '''.#..#.# #.#.... .#.....''' puz = Puzzle(2016, 8) screen = Screen() for line in puz.input_data.split('\n'): screen(line) puz.answer_a = screen.voltage print('Part 1:', puz.answer_a) puz.answer_b = ocr(str(screen)) print('Part 2:', puz.answer_b)
memory[new_addr] = val else: memory[addr] = val return memory if __name__ == '__main__': from aocd.models import Puzzle t = '''mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X mem[8] = 11 mem[7] = 101 mem[8] = 0''' assert sum(part1(t).values()) == 165 t = '''mask = 000000000000000000000000000000X1001X mem[42] = 100 mask = 00000000000000000000000000000000X0XX mem[26] = 1''' assert sum(part2(t).values()) == 208 puz = Puzzle(2020, 14) mem = part1(puz.input_data) puz.answer_a = sum(mem.values()) print(f'Part 1: {puz.answer_a}') mem = part2(puz.input_data) puz.answer_b = sum(mem.values()) print(f'Part 2: {puz.answer_b}')
fish[2], fish[1], ) if __name__ == "__main__": from aocd.models import Puzzle test_vals = process_input("""3,4,3,1,2""") for _ in range(80): timer(test_vals) assert sum(test_vals.values()) == 5934 puz = Puzzle(2021, 6) data = process_input(puz.input_data) for _ in range(80): timer(data) puz.answer_a = sum(data.values()) print(f"Part 1: {puz.answer_a}") for _ in range(256 - 80): timer(data) puz.answer_b = sum(data.values()) print(f"Part 2: {puz.answer_b}")
for taken in get_grab_options(items): for new_items in get_move_options(items, taken, top_floor): if is_safe(new_items): frontier.appendleft((tuple(new_items), moves + 1)) else: raise RuntimeError('Failed to achieve goal!') return moves if __name__ == '__main__': from aocd.models import Puzzle s = '''The first floor contains a hydrogen-compatible microchip and a lithium-compatible microchip. The second floor contains a hydrogen generator. The third floor contains a lithium generator. The fourth floor contains nothing relevant.''' start = parse(s) assert breadth_first_search(start) == 11 puz = Puzzle(2016, 11) layout = parse(puz.input_data) puz.answer_a = breadth_first_search(layout) print('Part 1:', puz.answer_a) new_layout = parse(puz.input_data) new_layout = new_layout[:-1] + [0, 0, 0, 0] + new_layout[-1:] puz.answer_b = breadth_first_search(new_layout) print('Part 2:', puz.answer_b)
from aocd.models import Puzzle from util import * DatabaseEntry = Tuple[int, int, str, str] def parse_line(line) -> DatabaseEntry: match = re.match(r"(\d+)-(\d+) (.): (.+)", line) if match: groups = match.groups() return int(groups[0]), int(groups[1]), groups[2], groups[3] else: raise RuntimeError(f"Could not parse {line}!") def part_a(inputs: List[DatabaseEntry]) -> int: return sum([e[0] <= e[3].count(e[2]) <= e[1] for e in inputs]) def part_b(inputs: List[DatabaseEntry]) -> int: return sum([(e[3][e[0] - 1] == e[2]) is not (e[3][e[1] - 1] == e[2]) for e in inputs]) puzzle = Puzzle(year=2020, day=2) puzzle_inputs = [parse_line(l) for l in puzzle.input_data.split("\n")] puzzle.answer_a = part_a(puzzle_inputs) puzzle.answer_b = part_b(puzzle_inputs)
new_spot = grid[new_y][new_x] if new_spot != '#': options.append( (n, new_loc, (nums | {new_spot}) if new_spot in all_nums else nums)) else: raise RuntimeError('No path found!') return shortest if __name__ == '__main__': from aocd.models import Puzzle maze = '''########### #0.1.....2# #.#######.# #4.......3# ###########''' assert shortest_path(maze.split('\n')) == 14 assert shortest_path_return(maze.split('\n')) == 20 puz = Puzzle(2016, 24) puz.answer_a = shortest_path(puz.input_data.split('\n')) print('Part 1:', puz.answer_a) puz.answer_b = shortest_path_return(puz.input_data.split('\n')) print('Part 2:', puz.answer_b)