#!/usr/bin/env python3 from pathlib import Path def part_1(input): result = 0 x_size = len(input[0].strip()) y_size = len(input) nodes = {(x, y): int(v) for y, line in enumerate(input) for x, v in enumerate(line.strip())} start = (0, 0) end = (x_size - 1, y_size - 1) cost = {start: 0} queue = set([start]) done = set() neighbors = set([(-1, 0), (0, -1), (0, 1), (1, 0)]) while len(queue): cur_cost = None for n in queue: if cur_cost == None or cost[n] < cur_cost: cur_cost = cost[n] current = n queue.remove(current) (xc, yc) = current next = set() for (xn, yn) in neighbors: nbr = (xc + xn, yc + yn) if nbr in nodes and not nbr in done: next.add(nbr) for n in next: next_cost = cur_cost + nodes[n] if not n in cost or next_cost < cost[n]: cost[n] = next_cost queue.add(n) done.add(current) result = cost[end] print("Part 1 result:", result) def part_2(input): result = 0 x_size = len(input[0].strip()) y_size = len(input) repeat = 5 nodes = {} for y, line in enumerate(input): for x, v in enumerate(line.strip()): for i in range(repeat): for j in range(repeat): xi = x + (x_size * i) yj = y + (y_size * j) vi = (int(v) + i + j) if 10 <= vi: vi -= 9 nodes[(xi, yj)] = vi start = (0, 0) end = ((x_size * repeat) - 1, (y_size * repeat) - 1) cost = {start: 0} queue = set([start]) done = set() neighbors = set([(-1, 0), (0, -1), (0, 1), (1, 0)]) while len(queue): cur_cost = None for n in queue: if cur_cost == None or cost[n] < cur_cost: cur_cost = cost[n] current = n queue.remove(current) (xc, yc) = current next = set() for (xn, yn) in neighbors: x = xc + xn y = yc + yn if 0 <= x < (x_size * repeat) and 0 <= y < (y_size * repeat): if not (x, y) in done: next.add((x, y)) for n in next: next_cost = cur_cost + nodes[n] if not n in cost or next_cost < cost[n]: cost[n] = next_cost queue.add(n) done.add(current) result = cost[end] print("Part 2 result:", result) input = list() p = Path(__file__).with_name('input.txt') with open(p) as f: input = f.readlines() part_1(input) part_2(input)