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
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)
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)
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
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)
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 assert find_sequential_bus_timestamp([1789, 37, 47, 1889]) == 1202161486 puz.answer_b = find_smallest_bus_timestamp(data[1]) print(f"Part 2: {puz.answer_b}")
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 aocd.models import Puzzle import intcode2019 from functools import reduce from operator import xor import string import re from copy import deepcopy from collections import defaultdict, Counter, deque from itertools import product, permutations puzzle = Puzzle(year=2019, day=9) program = puzzle.input_data program_intcode = intcode2019.convert(program) inp = deque(['2']) # program_intcode = intcode2019.convert('109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99') # inp = None new_program, output, curr_instr = intcode2019.parse(program_intcode, inp) puzzle.answer_b = output[0]
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}')
from aocd.models import Puzzle from functools import reduce from operator import xor import string import re from copy import deepcopy puzzle = Puzzle(year=2017, day=17) steps = 348 buffer = [0] pos = 0 value = 0 buffer_len = 1 for i in range(1, 50000000 + 1): pos = (pos + steps) % buffer_len if pos == 0: value = i buffer_len += 1 pos = (pos + 1) % buffer_len puzzle.answer_b = value
] 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], ] assert count_overlaps(grid) == 12 grid = build_grid(data, True) puz.answer_b = count_overlaps(grid) print(f"Part 2: {puz.answer_b}")
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)
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}')
] 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 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)
if need[name] == 0: del need[name] return ore maxOre = 1000000000000 result = 0 while maxOre > 0: ore = 0 cnt = maxOre // int(puzzle.answer_a) need = {"FUEL": cnt} result += cnt while len(need) > 0: if (ore > maxOre): maxOre = 0 result -= cnt break needTmp = need.copy() for name, val in needTmp.items(): ore = makeReaction(ore, val, name) maxOre -= ore if (maxOre < int(puzzle.answer_a)): break #print("result:",result, " cnt:",cnt," maxOre",maxOre) print("2019-Day14-B result:", result) puzzle.answer_b = result
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)
data = puzzle.input_data.split("\n") summary = 0 def fuelCount(mass): """Fuel required to launch a given module is based on its mass. Specifically, to find the fuel required for a module , take its mass, divide by three, round down, and subtract 2.""" tmpVal = int(mass) / 3 tmpVal = int(tmpVal) return tmpVal - 2 def fuel_for_fuel(mass): tmpsum = 0 tmp_val = mass while tmp_val > 0: tmpsum += tmp_val tmp_val = fuelCount(tmp_val) return tmpsum - mass for tmp in data: val = fuelCount(tmp) summary += val summary += fuel_for_fuel(val) print("2019-Day1-B result: ", summary) puzzle.answer_b = summary
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}')