2024-12-18 - RAM Run
(original .ipynb)%%time from advent import dijkstra puzzle_input_str = open("./puzzle_input/day18.txt").read() test_input_str = """5,4 4,2 4,5 3,0 2,1 6,3 2,4 1,5 0,6 3,3 2,6 5,1 1,2 5,5 2,5 6,5 1,4 0,4 6,4 1,1 6,1 1,0 0,5 1,6 2,0""" def parse_input(input_str): def wrapped(): for line in input_str.splitlines(): c, r = line.split(",") yield int(r), int(c) return list(wrapped()) def neighbours(r, c, max_r, max_c): candidates = ( (r-1, c), (r+1, c), (r, c-1), (r, c+1) ) for maybe_r, maybe_c in candidates: if maybe_r == r and maybe_c == c: continue if maybe_r >= max_r or maybe_r < 0: continue if maybe_c >= max_c or maybe_c < 0: continue yield (maybe_r, maybe_c) def build_graph(max_r, max_c, corrupted_bytes): graph = {} for r in range(max_r+1): for c in range(max_c+1): children = {} for neighbour in neighbours(r, c, max_r+1, max_c+1): if neighbour not in corrupted_bytes: children[neighbour] = 1 graph[(r,c)] = children return graph def part_one(input_str, dest_r=70, dest_c=70, num_bytes=1024): corrupted_bytes = parse_input(input_str) graph = build_graph(dest_r, dest_c, corrupted_bytes[:num_bytes]) return dijkstra(graph, (0,0), (dest_r, dest_c)) assert 22 == part_one(test_input_str, 6, 6, 12) print("part one:", part_one(puzzle_input_str))
part one: 348 CPU times: user 3.14 s, sys: 3.82 ms, total: 3.14 s Wall time: 3.15 s
from math import inf def has_solution(dest_r, dest_c, corrupted_bytes): graph = build_graph(dest_r, dest_c, corrupted_bytes) return inf != dijkstra(graph, (0,0), (dest_r, dest_c)) def check_solution(dest_r, dest_c, num_bytes, corrupted_bytes): previous = has_solution(dest_r, dest_c, corrupted_bytes[:num_bytes-1]) current = has_solution(dest_r, dest_c, corrupted_bytes[:num_bytes]) if previous: if current: return -1 return 0 return 1 def part_two(input_str, dest_r=70, dest_c=70, num_bytes=1024): all_corrupted_bytes = parse_input(input_str) lower = num_bytes upper = len(all_corrupted_bytes) - 1 pivot = lower + ((upper - lower) // 2) while upper != lower: result = check_solution(dest_r, dest_c, pivot, all_corrupted_bytes) if result == 0: return all_corrupted_bytes[pivot-1][::-1] if result < 0: lower = pivot else: upper = pivot pivot = lower + ((upper - lower) // 2) raise Exception("No solution found, wtf") assert (6, 1) == part_two(test_input_str, 6, 6, 12) print("part two:", part_two(puzzle_input_str))
part two: (54, 44)