diff --git a/python/day12/day12_1.py b/python/day12/day12_1.py index 51761c3..9ae7fbb 100644 --- a/python/day12/day12_1.py +++ b/python/day12/day12_1.py @@ -48,7 +48,7 @@ class Node: return children -def a_start_search(start, goal): +def a_star_search(start, goal): start_node = Node(start[0], start[1]) start_node.g = 0 openSet = [start_node] @@ -86,4 +86,4 @@ def not_in_set(node, openset): return True -print(a_start_search(s, e)) +print(a_star_search(s, e)) diff --git a/python/day12/day12_2.py b/python/day12/day12_2.py index e69de29..010f245 100644 --- a/python/day12/day12_2.py +++ b/python/day12/day12_2.py @@ -0,0 +1,75 @@ +lines = open("input.txt", "r").read().splitlines() + +relief = [] +starting_points = [] +points = [] +s = None +e = None +for i, line in enumerate(lines): + els = [] + for j, letter in enumerate(line): + if letter == "a": + starting_points.append((i, j)) + if letter == "S": + els.append(1) + s = (i, j) + starting_points.append((i, j)) + elif letter == "E": + els.append(26) + e = (i, j) + else: + els.append(ord(letter) - 96) + points.append((i, j)) + relief.append(els) + + +def neighbours(node): + n = [] + if node[0] > 0 and relief[node[0]][node[1]] + 1 >= relief[node[0] - 1][node[1]]: + n.append((node[0] - 1, node[1])) + if ( + node[0] < len(relief) - 1 + and relief[node[0]][node[1]] + 1 >= relief[node[0] + 1][node[1]] + ): + n.append((node[0] + 1, node[1])) + if node[1] > 0 and relief[node[0]][node[1]] + 1 >= relief[node[0]][node[1] - 1]: + n.append((node[0], node[1] - 1)) + if ( + node[1] < len(relief[0]) - 1 + and relief[node[0]][node[1]] + 1 >= relief[node[0]][node[1] + 1] + ): + n.append((node[0], node[1] + 1)) + return n + + +def h(node): + return abs(e[0] - node[0]) + abs(e[1] - node[1]) + + +def a_star_search(start, goal): + queue = [start] + gscore = {x: 9999999 for x in points} + gscore[start] = 0 + fscore = {x: 9999999 for x in points} + fscore[start] = h(start) + while len(queue) > 0: + queue = sorted({x: fscore[x] for x in queue}, key=lambda x: x[1]) + current = queue.pop(0) + if current[0] == goal[0] and current[1] == goal[1]: + return fscore[current] + for n in neighbours(current): + newg = gscore[current] + 1 + if newg < gscore[n]: + gscore[n] = newg + fscore[n] = newg + h(n) + if n not in queue: + queue.append(n) + return None + + +scenic = [] +for starting_point in starting_points: + scene = a_star_search(starting_point, e) + if scene is not None: + scenic.append(scene) +print(sorted(scenic)[0])