Day 16 Part 2 works now!
This commit is contained in:
1 parent
e88cfd643a
commit
3298e5cc8a
4 files changed
+386
-15
No files matched your search
@@ -0,0 +1,141 @@
|
|||||||
|
--- Day 16: Reindeer Maze ---
|
||||||
|
|
||||||
|
It's time again for the Reindeer Olympics! This year, the big event is the Reindeer Maze, where the Reindeer compete for the lowest score.
|
||||||
|
|
||||||
|
You and The Historians arrive to search for the Chief right as the event is about to start. It wouldn't hurt to watch a little, right?
|
||||||
|
|
||||||
|
The Reindeer start on the Start Tile (marked S) facing East and need to reach the End Tile (marked E). They can move forward one tile at a time (increasing their score by 1 point), but never into a wall (#). They can also rotate clockwise or counterclockwise 90 degrees at a time (increasing their score by 1000 points).
|
||||||
|
|
||||||
|
To figure out the best place to sit, you start by grabbing a map (your puzzle input) from a nearby kiosk. For example:
|
||||||
|
|
||||||
|
###############
|
||||||
|
#.......#....E#
|
||||||
|
#.#.###.#.###.#
|
||||||
|
#.....#.#...#.#
|
||||||
|
#.###.#####.#.#
|
||||||
|
#.#.#.......#.#
|
||||||
|
#.#.#####.###.#
|
||||||
|
#...........#.#
|
||||||
|
###.#.#####.#.#
|
||||||
|
#...#.....#.#.#
|
||||||
|
#.#.#.###.#.#.#
|
||||||
|
#.....#...#.#.#
|
||||||
|
#.###.#.#.#.#.#
|
||||||
|
#S..#.....#...#
|
||||||
|
###############
|
||||||
|
|
||||||
|
There are many paths through this maze, but taking any of the best paths would incur a score of only 7036. This can be achieved by taking a total of 36 steps forward and turning 90 degrees a total of 7 times:
|
||||||
|
|
||||||
|
|
||||||
|
###############
|
||||||
|
#.......#....E#
|
||||||
|
#.#.###.#.###^#
|
||||||
|
#.....#.#...#^#
|
||||||
|
#.###.#####.#^#
|
||||||
|
#.#.#.......#^#
|
||||||
|
#.#.#####.###^#
|
||||||
|
#..>>>>>>>>v#^#
|
||||||
|
###^#.#####v#^#
|
||||||
|
#>>^#.....#v#^#
|
||||||
|
#^#.#.###.#v#^#
|
||||||
|
#^....#...#v#^#
|
||||||
|
#^###.#.#.#v#^#
|
||||||
|
#S..#.....#>>^#
|
||||||
|
###############
|
||||||
|
|
||||||
|
Here's a second example:
|
||||||
|
|
||||||
|
#################
|
||||||
|
#...#...#...#..E#
|
||||||
|
#.#.#.#.#.#.#.#.#
|
||||||
|
#.#.#.#...#...#.#
|
||||||
|
#.#.#.#.###.#.#.#
|
||||||
|
#...#.#.#.....#.#
|
||||||
|
#.#.#.#.#.#####.#
|
||||||
|
#.#...#.#.#.....#
|
||||||
|
#.#.#####.#.###.#
|
||||||
|
#.#.#.......#...#
|
||||||
|
#.#.###.#####.###
|
||||||
|
#.#.#...#.....#.#
|
||||||
|
#.#.#.#####.###.#
|
||||||
|
#.#.#.........#.#
|
||||||
|
#.#.#.#########.#
|
||||||
|
#S#.............#
|
||||||
|
#################
|
||||||
|
|
||||||
|
In this maze, the best paths cost 11048 points; following one such path would look like this:
|
||||||
|
|
||||||
|
#################
|
||||||
|
#...#...#...#..E#
|
||||||
|
#.#.#.#.#.#.#.#^#
|
||||||
|
#.#.#.#...#...#^#
|
||||||
|
#.#.#.#.###.#.#^#
|
||||||
|
#>>v#.#.#.....#^#
|
||||||
|
#^#v#.#.#.#####^#
|
||||||
|
#^#v..#.#.#>>>>^#
|
||||||
|
#^#v#####.#^###.#
|
||||||
|
#^#v#..>>>>^#...#
|
||||||
|
#^#v###^#####.###
|
||||||
|
#^#v#>>^#.....#.#
|
||||||
|
#^#v#^#####.###.#
|
||||||
|
#^#v#^........#.#
|
||||||
|
#^#v#^#########.#
|
||||||
|
#S#>>^..........#
|
||||||
|
#################
|
||||||
|
|
||||||
|
Note that the path shown above includes one 90 degree turn as the very first move, rotating the Reindeer from facing East to facing North.
|
||||||
|
|
||||||
|
Analyze your map carefully. What is the lowest score a Reindeer could possibly get?
|
||||||
|
|
||||||
|
Your puzzle answer was 143564.
|
||||||
|
--- Part Two ---
|
||||||
|
|
||||||
|
Now that you know what the best paths look like, you can figure out the best spot to sit.
|
||||||
|
|
||||||
|
Every non-wall tile (S, ., or E) is equipped with places to sit along the edges of the tile. While determining which of these tiles would be the best spot to sit depends on a whole bunch of factors (how comfortable the seats are, how far away the bathrooms are, whether there's a pillar blocking your view, etc.), the most important factor is whether the tile is on one of the best paths through the maze. If you sit somewhere else, you'd miss all the action!
|
||||||
|
|
||||||
|
So, you'll need to determine which tiles are part of any best path through the maze, including the S and E tiles.
|
||||||
|
|
||||||
|
In the first example, there are 45 tiles (marked O) that are part of at least one of the various best paths through the maze:
|
||||||
|
|
||||||
|
###############
|
||||||
|
#.......#....O#
|
||||||
|
#.#.###.#.###O#
|
||||||
|
#.....#.#...#O#
|
||||||
|
#.###.#####.#O#
|
||||||
|
#.#.#.......#O#
|
||||||
|
#.#.#####.###O#
|
||||||
|
#..OOOOOOOOO#O#
|
||||||
|
###O#O#####O#O#
|
||||||
|
#OOO#O....#O#O#
|
||||||
|
#O#O#O###.#O#O#
|
||||||
|
#OOOOO#...#O#O#
|
||||||
|
#O###.#.#.#O#O#
|
||||||
|
#O..#.....#OOO#
|
||||||
|
###############
|
||||||
|
|
||||||
|
In the second example, there are 64 tiles that are part of at least one of the best paths:
|
||||||
|
|
||||||
|
#################
|
||||||
|
#...#...#...#..O#
|
||||||
|
#.#.#.#.#.#.#.#O#
|
||||||
|
#.#.#.#...#...#O#
|
||||||
|
#.#.#.#.###.#.#O#
|
||||||
|
#OOO#.#.#.....#O#
|
||||||
|
#O#O#.#.#.#####O#
|
||||||
|
#O#O..#.#.#OOOOO#
|
||||||
|
#O#O#####.#O###O#
|
||||||
|
#O#O#..OOOOO#OOO#
|
||||||
|
#O#O###O#####O###
|
||||||
|
#O#O#OOO#..OOO#.#
|
||||||
|
#O#O#O#####O###.#
|
||||||
|
#O#O#OOOOOOO..#.#
|
||||||
|
#O#O#O#########.#
|
||||||
|
#O#OOO..........#
|
||||||
|
#################
|
||||||
|
|
||||||
|
Analyze your map further. How many tiles are part of at least one of the best paths through the maze?
|
||||||
|
|
||||||
|
Your puzzle answer was 593.
|
||||||
|
|
||||||
|
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||||
+25
-15
@@ -3,7 +3,8 @@
|
|||||||
import sys, math
|
import sys, math
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
def dijkstra(graph, s, v, a):
|
|
||||||
|
def dijkstra(graph, v, a):
|
||||||
Q = [n for n in graph.keys()]
|
Q = [n for n in graph.keys()]
|
||||||
lq = len(Q)
|
lq = len(Q)
|
||||||
while len(Q) > 0:
|
while len(Q) > 0:
|
||||||
@@ -14,27 +15,33 @@ def dijkstra(graph, s, v, a):
|
|||||||
distance_update(graph, u,vo,a,v)
|
distance_update(graph, u,vo,a,v)
|
||||||
return v, a
|
return v, a
|
||||||
|
|
||||||
|
|
||||||
def distance_update(g, u, vo, a, v):
|
def distance_update(g, u, vo, a, v):
|
||||||
dist = 1 if vo[2] == u[2] else 1000
|
dist = 1 if vo[2] == u[2] else 1000
|
||||||
alt = a[u] + dist
|
alt = a[u] + dist
|
||||||
|
# joining the sets does not work because we never remove the older nodes!
|
||||||
if alt <= a[vo]:
|
if alt <= a[vo]:
|
||||||
|
if alt < a[vo]:
|
||||||
|
v[vo] = set([])
|
||||||
|
a[vo] = alt
|
||||||
v[vo].add(u)
|
v[vo].add(u)
|
||||||
v[vo] = v[vo].union(set(v[u]))
|
v[vo] = v[vo].union(set(v[u]))
|
||||||
if alt < a[vo]:
|
|
||||||
a[vo] = alt
|
|
||||||
|
|
||||||
def count_set(edges):
|
|
||||||
|
def count_set(edges, lab):
|
||||||
edg = set([])
|
edg = set([])
|
||||||
for e in edges:
|
for e in edges:
|
||||||
edg.add((e[0], e[1]))
|
edg.add((e[0], e[1]))
|
||||||
return len(edg)
|
lab[e[1]][e[0]] = 'O'
|
||||||
|
return edg
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
lab = [list(line.strip('\n')) for line in open(sys.argv[1])]
|
lab = [list(line.strip('\n')) for line in open(sys.argv[1])]
|
||||||
rot90 = {(0,-1): [(-1,0),(1,0)], (1,0): [(0,-1),(0,1)], (0,1): [(1,0),(-1, 0)], (-1,0): [(0,1),(0,-1)]}
|
rot90 = {(0,-1): [(-1,0),(1,0)], (1,0): [(0,-1),(0,1)], (0,1): [(1,0),(-1, 0)], (-1,0): [(0,1),(0,-1)]}
|
||||||
|
|
||||||
start = (1, len(lab)-2, (1,0))
|
start = (1, len(lab)-2, (1,0))
|
||||||
end = (len(lab[0])-2, 1)
|
end = (len(lab[0])-2, 1, (0,-1))
|
||||||
graph = {}
|
graph = {}
|
||||||
distance = {}
|
distance = {}
|
||||||
pred = {}
|
pred = {}
|
||||||
@@ -46,20 +53,23 @@ if __name__ == '__main__':
|
|||||||
pred[(x,y,d)] = set([])
|
pred[(x,y,d)] = set([])
|
||||||
graph[(x,y,d)] = []
|
graph[(x,y,d)] = []
|
||||||
for d1 in rot90[d]:
|
for d1 in rot90[d]:
|
||||||
graph[(x,y,d)].append((x,y,d1))
|
if not lab[y+d1[1]][x+d1[0]] == '#': graph[(x,y,d)].append((x,y,d1))
|
||||||
if lab[y+d[1]][x+d[0]] == '.' or lab[y+d[1]][x+d[0]] == 'E':
|
if lab[y+d[1]][x+d[0]] != '#':
|
||||||
graph[(x,y,d)].append((x+d[0], y+d[1], d))
|
graph[(x,y,d)].append((x+d[0], y+d[1], d))
|
||||||
distance[start] = 0
|
distance[start] = 0
|
||||||
v, a = dijkstra(graph, start, pred, distance)
|
v1, a1 = dijkstra(graph, pred, distance)
|
||||||
print([a[end[0], end[1], d] for d in [(0,1), (0,-1), (1,0), (-1,0)]], [1+count_set(v[end[0], end[1], d]) for d in [(0,1), (0,-1), (1,0), (-1,0)]])
|
d1 = count_set(v1[end], lab)
|
||||||
|
|
||||||
# challenge 1
|
# challenge 1
|
||||||
res1 = min([a[end[0], end[1], d] for d in [(0,1), (0,-1), (1,0), (-1,0)]])
|
res1 = a1[end]
|
||||||
print(f"challenge 1:\n{res1}\n")
|
print(f"challenge 1:\n{res1}\n")
|
||||||
|
|
||||||
# challenge 2
|
# challenge 2, needed some reddit help again...
|
||||||
ind = [a[end[0], end[1], d] for d in [(0,1), (0,-1), (1,0), (-1,0)]].index(res1)
|
d1.add((end[0],end[1]))
|
||||||
d = [(0,1), (0,-1), (1,0), (-1,0)][ind]
|
d1.add((start[0], start[1]))
|
||||||
res2 = 1+count_set(v[end[0], end[1], d])
|
res2 = len(d1)
|
||||||
print(f"challenge 2:\n{res2}")
|
print(f"challenge 2:\n{res2}")
|
||||||
|
|
||||||
|
for line in lab:
|
||||||
|
print(''.join(line))
|
||||||
|
|
||||||
+141
@@ -0,0 +1,141 @@
|
|||||||
|
#############################################################################################################################################
|
||||||
|
#...#.....#.......#...........#...#.............#.......#.........#.....................#.............#.........#.....#.......#.........#..E#
|
||||||
|
#.#.#.#.###.#.###.#####.#.#.#.#.#.#.###.#######.#######.#.#####.###.#.#######.###.#.#.#.#.#.###.#####.###.#####.#.###.#.###.#.#######.#.#.#O#
|
||||||
|
#.#...................#.....#...#.#.#.#.......#.........#.....#.....#.........#...#.#.#.#.#.........#.....#...#...#...#.#...#...#.....#...#O#
|
||||||
|
###.#.#.#.#####.#####.#.#.#######.#.#.#######.#######.#######.###########.#####.#.###.#.#.#########.#######.#.#.###.#####.#####.#.###.#####O#
|
||||||
|
#...#.#...#...#.#.#...#...#...#...#...#.....#.....#.#.#...#.............#...#...#.#...#...#.......#.....................#.#.....#...#OOOOO#O#
|
||||||
|
#.###.#####.#.#.#.#.###.#.###.#.#####.#.###.#####.#.#.#.#.#.#####.#.###.#####.#####.#########.#.#.#####.#.#####.#.###.#.#.#.#######.#O###O#O#
|
||||||
|
#.....#...#.#.#.#...#...#...#.......#.#...#...#...#...#.#...#...#.#...#.......#.....#.........#...#.....#.....#.#.#...#...#.#.......#O..#O#O#
|
||||||
|
#.#####.###.#.#.#.###.#.###.#.#######.###.#.#.#.#.#####.#####.#.#.###.###.#####.#####.#############.#####.###.#.#.###.#####.###.#####O#.#O#O#
|
||||||
|
#.......#...#...#...#...#...#.#.....#.....#...#.#.#.....#.....#...#...#...#...#.....#...#...........#.#...#.#...#...#...#.....#...#..O..#OOO#
|
||||||
|
#####.###.#####.###.###.#.#.###.###.#######.###.#.#.#########.#.###.#######.#.#####.###.#.###########.#.###.###.###.#.#.#####.###.#.#O#.###.#
|
||||||
|
#...#.#...#.......#.......#.#...#...#.....#.#.#.#.#...#...#...#.#...#.....#.#.........#.#.....#.........#.....#.....#.#.....#.....#.#O#.#...#
|
||||||
|
#.###.#.###.###.###########.#.###.#.#.#.#.#.#.#.#####.#.#.#.###.#.#.#.###.#.#########.#.#####.#.#####.###.###.#######.#####.#######.#O#.#.###
|
||||||
|
#.....#.#.......#.......................#.#.....................#.#.#...#...#.......#.......#.#.#...#.#...#.#.#.#.........#.#.....#.#O#.#...#
|
||||||
|
#.#####.#.#####.#.#.#.#######.#.#.#.#.#.#.#.#.###.#######.#####.#.#####.#####.###.#.#######.#.###.#.#.###.#.#.#.#.#########.#.###.###O#.###.#
|
||||||
|
#.....#.#.....#...#.#.#.........#.#.#.#.....#...#.........#...#.#.........#...#.....#...#...#.#...#.#...#.#.#.#...#.....#...#...#...#O......#
|
||||||
|
#######.#####.#####.#.#####.###.#.###.###.#.#.#####.#######.#.###########.#.###.#####.###.###.#.###.###.#.#.#.#####.###.#.###.#.###.#O###.###
|
||||||
|
#.......#...#.#...#...#...#...#.#.....#...#...#...#.......#.#.#.......#...#.#.#.#...#.....#.#...#.#.#.#...#...#.....#...#.#...#.#.#..O#...#.#
|
||||||
|
#.#######.#.#.###.#####.#.#.#.#.#######.#######.#.#.#######.#.#.#####.###.#.#.#.#.#.#.#####.#.#.#.#.#.#####.###.#.###.###.#.###.#.###O#.###.#
|
||||||
|
#...#...#.#.............#.#...#...#.....#...#...#...#.........#...#.#...#.#.#.....#.#.......#.....#.#.....#.....#...#.#...#...#.#OOOOO#.....#
|
||||||
|
###.#.#.#.#########.#.###.###.###.###.###.#.#.#.###.#.#######.###.#.###.###.#.###.#.#######.#######.#.###.#######.#.#.#.#######.#O#########.#
|
||||||
|
#...#.#...#...#.......#.........#...#.#...#.#.....#...#.....#...#.#.........#.....#.............#...#...#.#.....#.#.....#.......#OOOOOOO..#.#
|
||||||
|
#.#####.###.#.###############.#####.#.#.###.#####.#######.#####.#.#####################.#########.#####.#.#.#####.#####.#.#.###.#######O###.#
|
||||||
|
#.#...#.#...#.......#.....#.......#...#...#.......#.......#.....#.#...#.....#.........#...........#.....#.#.#.....#.....#.#...#OOOOOOOOO#...#
|
||||||
|
#.#.#.###.#########.#.###.#.###.###.#.###.#.#######.#.#####.###.#.#.#.###.#.#.#####.#.#.#########.#.#.#.#.#.#.#####.#.#####.#.#O#####.###.###
|
||||||
|
#...#...#.#.....#.#.#...#...#.#.......#.....#.....#.#.....#...#.....#...#.#.#.#...#.#.#.............#...#...#.#...#.#.#...#.#..OOO..#.#...#.#
|
||||||
|
#.#####.#.#.###.#.#.###.#####.#########.#####.###.###.#.#.###.#.#######.#.###.#.#.#.###.#############.#.#.#.#.#.###.#.#.#.#######O#.###.###.#
|
||||||
|
#.#...#.....#.....#.....#.....#.......#.....#...#...#...#...#.#.....#...#.......#.#.#...#...#.......#.#.#.#...#.#...#...#.#.....#O#.#...#OOO#
|
||||||
|
#.#.#.#.#########.###########.#.###.#######.###.###.#######.#.###.###.#############.#.#####.#.#####.###.#.#.###.#.#######.#.###.#O#.#.###O#O#
|
||||||
|
#.#.#.#...#...#.#.....#.....#...#.#.#.....#...#.#.#.#.......#...#.#...#.........#...#.......#.#...#...#.#.#.#...#.#.....#.#.#...#O#...#OOO#O#
|
||||||
|
#.#.#.#.###.#.#.#####.###.#.#.###.#.#.###.#.#.#.#.#.#.#####.###.#.#.###.#######.#.#######.###.#.#.###.#.#.#.#.#.#.#.###.#.#.#.###O#####O###O#
|
||||||
|
#.#.#.#.#...#.#.#...#.#...#.#.#...#.....#...#.....#.#.....#.#.#.#.#.#.......#...#.......#.#...#.#...#.#.#.#.#.#...#.#...#...#...#O#OOOOO#..O#
|
||||||
|
###.#.###.###.#.#.#.#.#.###.#.#.#.#########.#######.#.###.#.#.#.###.#######.#.#######.###.#.#####.###.#.###.#.###.#.###.#######.#O#O#######O#
|
||||||
|
#...#.....#.#.#.#.#...#.#...#.#.#...#.......#.......#...#.....#.....#...#.....#.......#...#.#.....#...#.#...#.....#...#.........#O#OOO#...#O#
|
||||||
|
#.#########.#.#.#.#####.###.#.###.#.#.#####.#.#########.#.#########.#.#.#.###.#.#######.###.#.#.###.#.#.#.#########.#.#########.#O###O#.#.#O#
|
||||||
|
#...#.......#.#.#.#.......#.#...#.#...#.....#...........#.#...#.............#.#.#.......#.#.#.#...#...#.#.#.......#.#...#.......#OOOOO#.#.#O#
|
||||||
|
###.#.#####.#.#.#.#######.#.###.#.#.#####.###########.#.###.#.#.#####.#####.#.#.#.#######.#.###.#.###.#.#.###.###.#.###.#.#####.#.#####.#.#O#
|
||||||
|
#...#.....#...#.......#...#...#...#.#...#...#...#.....#.....#.#.#...#.#...#.....#.........#...#.#...#...#.....#.#.#.#.#.#.#.#...#.#.....#.#O#
|
||||||
|
#.#######.###########.#.#.###.###.#.#.#.###.#.#.#.#.#######.#.#.#.#.#.###.#.#######.#####.###.#.###.###.#####.#.#.#.#.#.#.#.#.#.###.#####.#O#
|
||||||
|
#.#.......#.........#...#...#...#.#...#...#.#.#...#.#.....#.#.......#...#.#...#.....#...#.#.#.#...#...#.#.......#.#...#...#.#.#.......#...#O#
|
||||||
|
#.#.#########.###.#.#######.###.#########.#.#.#####.#.#.#.#####.#.###.#.#.#.###.###.#.#.#.#.#.#####.#.#.#.#####.#.#######.#.#.#.#######.###O#
|
||||||
|
#.#.#.........#...#...#.....#...#.........#.#.#.....#.#.#.....#.#...........#...#.....#.#...#.....#.#.#.#.#...#.#.#.....#...#.#.....#...#.#O#
|
||||||
|
#.#.###.#########.###.#.#.###.###.###.#####.#.###.###.#.#####.###.#####.#.###.###.#####.#.#######.#.###.#.#.#.#.#.#.###.#####.#.###.#.###.#O#
|
||||||
|
#.#.....#.#.........#.#.........#.#...#.....#.....#...#.....#...#.#...#.#...#.#...#.....#.#.......#...#.#...#.#.#...#...#...#.......#.#...#O#
|
||||||
|
#.#######.#.#.#.#.###.#.#######.#.#.###.#####.#.#.#.#######.###.#.#.###.#.#.#.#.###.#######.#######.#.#.#####.#.#####.###.#.###.#####.#.###O#
|
||||||
|
#.............#.#.#...#.#.....#...#.....#...#.#.#.#.#...#.........#.....#.#...#...#.......#...#.....#.......#.#.#...#.......#.........#OOOOO#
|
||||||
|
#.#.#.#.#####.#.#.#.###.#.###.#####.#####.#.#.#.#.#.#.###.#.#######.###.#.#.#####.#######.#.#.###########.#.#.#.#.#.###.###.#.#.#.#####O#####
|
||||||
|
#.#.#.#.#...#.#.#.#.#...#.#...#.....#...#.#.#.#.#.#.#...#.......#.#.....#...#...#...#...#.#.#...........#.....#...#...#...#.#.#.#.....#O#OOO#
|
||||||
|
#.#.#.#.#.#.#.#.#.#.#.###.#.###.#####.#.#.#.#.#.#.#.###.#######.#.#####.###.#.#####.###.#.#####.#######.###.#######.#.###.#.#.#.#####.#O#O#O#
|
||||||
|
#.....#...#...#...#.#...#.#...#...#...#...#...#.#.#...#.......#.....#.....#.#.....#...#.......#.#.....#...#...#.....#.....#.#.#.#.....#OOO#O#
|
||||||
|
#.#.#.#.#####.###.#.###.#.###.###.###.###.###.#.#####.#.#.###.#.###.#.###.#.###.#####.#######.#.#.###.###.#.#.#.###.#.#.#.#.#.#.#.#########O#
|
||||||
|
#.#.#.#.#...#.....#...#.#.#.#.#.......#...#...#.#.....#.#...#.#...#.....#.......#...#.......#.#.#...#.....#.#...#...#...#.#...#...#OOOOOOOOO#
|
||||||
|
#.#.#.###.#.#.###.###.###.#.#.#.#######.###.###.#.#####.#.#.#.###.###.###.#######.#.#######.#.###.#.#.#####.#.#.#.#######.#####.###O#########
|
||||||
|
#.#.#.#...#...#...#...#...#...#.#...#...#...#.....#.....#...#...#...#.#...#.......#.........#...#.#.#.#...#.#...#.......#...#..OOO#O#.....#.#
|
||||||
|
#.###.#.#.###.#.###.###.###.#####.#.###.#.#######.#####.#.###.#####.###.###.###################.###.###.#.#.###########.###.#.#O#O#O#.#.#.#.#
|
||||||
|
#...#...#...#.#.#...#.....#.......#...#.#.......#.....#.#.#...#...#.....#...#...#...........#.....#.#...#.#...........#.....#.#O#OOO#.#.#.#.#
|
||||||
|
###.#####.#.#.#.#.#.#.###.###########.#.#######.#####.###.#####.#.#######.###.#.#.#####.#.#.#.###.#.#.###.###.#######.#######.#O#######.#.#.#
|
||||||
|
#...#...#.#.#.#...#.#...#.#.......#...#...#.....#...#.....#...#.#.....#...#...#...#...#.#.#...#...#.#...#.#...#.....#.#.....#.#O........#.#.#
|
||||||
|
#.###.#.#.#.#.###.#.###.#.#.#####.#.#####.#.#######.###.#.#.#.#.#####.#.###.#########.#.#.#####.###.#.###.#####.###.###.###.#.#O#########.#.#
|
||||||
|
#.#...#.#.#...#.....#.#.#.#.#...#.#.......#.......#.#...#...#.....#...#.#.....#.......#.#.#...#.#.....#...#.....#.#.....#.#...#OOO..........#
|
||||||
|
#.#.#.#.#.###.#.#####.#.#.#.###.#.#######.#.#####.#.#.#####.#######.###.#####.#.#####.#.#.#.#.#.#######.###.#####.#######.#######O###.#.###.#
|
||||||
|
#...#.#...#...#.#.......#.#...#.....#...#.#.....#.#.#.#...#.......#...#.....#.#.#...#.#...#.#...#.....#...#.#.#.......#.........#O#...#.....#
|
||||||
|
#.###.###.#.#.#.#########.###.#.#####.#.#.#######.#.#.#.#.#.#####.#.#.#####.#.#.#.#.#.#.###.#####.###.###.#.#.#.###.###.#.#.###.#O#.###.#####
|
||||||
|
#.#...#...#.#.............#...#.#.....#...#.......#.#...#...#...#.#.#.#.....#.#.#.#.#.#.....#.#...#.#.....#.#.#.#.#.....#...#.#.#O#.#.#...#.#
|
||||||
|
#.#.###.#.#.#.###.#.#.#####.#####.#######.#.#######.#########.###.#.#.#.#####.#.#.#.###.#.###.#.#.#.#####.#.#.#.#.###.###.###.#.#O#.#.###.#.#
|
||||||
|
#.#...#.#...#...#...#.#...#.........#...#...#.#.............#...#...#.#.#.....#...#.....#...#...#.#.....#.#.#.....#...#...#.#...#O#.#.....#.#
|
||||||
|
#.###.#######.#.#.#.###.#.###########.#.#####.#.#########.###.#.###.#.#.###.###.#####.#####.###.#.#.###.#.#.#######.#.#.###.#.###O#.#.#####.#
|
||||||
|
#.....#.......#...#.....#.#...........#.#...#...#.....#.#...#.#.....#.#...#...#.#...#.#...#...#.#.#...#...#.#.....#.#.#.#...#..OOO..#.#.....#
|
||||||
|
#.#.###.#######.#########.#.#####.#####.#.#.#.###.###.#.###.#.#######.###.###.#.#.#.#.###.###.###.###.#####.#.###.#.#.#.#.###.#O#####.#.#####
|
||||||
|
#.#.....#.....#.#.#.....#...#...#...#...#.#.#.#...#.#...#.#.#.........#...#...#.#.#.#.#.....#.#...#.#.#.....#...#...#.#.#.....#OOO#...#.....#
|
||||||
|
#.#.#######.#.#.#.#.###.###.#.#.#####.###.#.#.###.#.###.#.#.#########.#.###.###.#.#.#.#.#####.#.###.#.#.#####.#.#####.#.#####.#O#O#.#######.#
|
||||||
|
#.#.......#.#...#.#.#.#...#.#.#...#.......#.....#.#.....#.#.....#.....#.#.....#.#.#.#...#.....#.#.....#.#...#.#...#.#.......#.#O#O#.........#
|
||||||
|
#.#######.#.#####.#.#.###.#.#.###.#.#######.###.#.###.###.#####.#.#######.###.###.#.###.#.#####.#.#####.#.###.###.#.#.#####.###O#O#########.#
|
||||||
|
#...#.#...#...#...#.#...#.#.#.#...#.#.....#...#.#...#.....#.....#.......#.#...#.......#.#...#...#.#.....#.......#.#.#.......#..O#O#...#...#.#
|
||||||
|
#.#.#.#.#####.#.#.#.#.###.###.#.#.#.#.###.###.#.#.#.#####.#.#.#########.#.#.###.#####.#.###.#.#####.#########.###.#.#.#.###.#.#O#O#.#.#.#.#.#
|
||||||
|
#.#.#.#...#.....#.#.#...#.....#.#...#...#.....#.#.#...#...#.#.#.........#.....#.#.#...#.#.#.#.......#.......#.#...#.#.#.#...#.#O#O#.#.#.#...#
|
||||||
|
###.#.###.#######.#.#.#.#######.###.###.#######.#.###.#####.###.#.###.#.#.###.#.#.#.###.#.#.#####.###.#####.###.###.#.#.###.#.#O#O#.###.#####
|
||||||
|
#...#...#.......#...#.#.......#...#...#.........#...#.....#.....#...#.#.#...#.#...#.#.#...#.....#.#.....#.......#.....#...#.#.#OOO#...#...#.#
|
||||||
|
#.#####.#######.#.###.#####.#####.###.#.#####.###.#######.#########.#.#.#####.#.###.#.#.#######.#.###.#.#########.#######.#.#.#O#O###.###.#.#
|
||||||
|
#.#...#.......#.#...#.#...#.#...#.....#.#.........#.......#...#...#.#.#.....#...#...#...#.....#.#...#.#...#.............#.#....OOO..#.....#.#
|
||||||
|
#.#.#.#.###.#.#.#.#.#.#.#.#.#.#.###.###.###########.#####.#.#.#.###.#.#####.#####.###.###.###.#.###.#.###.#############.#.###.#O#O#.#.#####.#
|
||||||
|
#.#.#.#.#...#.#.#.#.#.#.#...#.#.......#.#...........#.....#.#...#...#.#...#.....#.#.#...#.#.#...#.#.#.#...#.......#.......#...#OOO#.#.#...#.#
|
||||||
|
#.#.#.#.#.#####.#.#.###.###.#.#######.#.#.#.#########.#####.#####.###.###.#####.#.#.###.#.#.#####.#.###.###.#####.#########.#####O#.#.#.#.#.#
|
||||||
|
#...#.#.#.......#.#...#...#.#.#.....#.....#.#...#...........#.....#.#.........#...#...#.#.#...#...#.#...#...#.#...#.......#.#.#..O#.#...#...#
|
||||||
|
#.#.#.#.#.#########.#.###.###.#####.#########.#.#.#########.#.#####.#####.###########.#.#.#.#.#.#.#.#.#.#.###.#.###.#####.#.#.#.#O#.#####.#.#
|
||||||
|
#...#...#.#.......#.#...#.#...#...#.....#.............#.....#...#.#.......#...........#.#.#.#.#.#.#...#...#...#.#...#...#.#.#....O..#.......#
|
||||||
|
#.#.###.#.###.###.#####.#.#.###.#.#.#####.###########.###.#.###.#.#.#######.###.#######.#.#.#.#.#.#####.#.#.###.#.###.#.#.#.###.#O#.#######.#
|
||||||
|
#.#...#.#...#...#.......#...#...#.#.....#...#...#.....#...#.#.#.......#.....#.#.....#.....#.#.#.#...#.....#.....#.#...#...#...#.#O#.#.....#.#
|
||||||
|
#.###.#.###.###.#########.###.###.#####.###.#.#.#.#.#.#.###.#.#.#.#####.#####.#####.#.###.#.#.#.###.#.#.#.#.#####.#####.#####.###O#.#.###.###
|
||||||
|
#...............#.#.....#.#...#...#.......#...#.#.#.#.#.......#.#.#.....#.........#...#.#.#.#.#.........#.#.....#.....#.......#OOO#.#.#.#...#
|
||||||
|
#.#####.#.#######.#.###.#.#.#.###.#.#.#.#.#####.#.#.#.#####.#.#.###.#####.###.#.#.#####.#.#.#####.#######.#####.#.###.#########O#.#.#.#.###.#
|
||||||
|
#.#...#...#.....#...#.#...#.#...#.#.#.#.......#.#.#.#.#...#...#.....#...#...#.#.#.#.......#.........#...#.#.....#...#.......#OOO#.#.#.#.#...#
|
||||||
|
#.#.#.#.###.#.###.###.#########.#.#.#.#.#.#####.#.###.#.#.###.#######.#####.#.#.#.#####.#.#.#########.#.#.###.#########.###.#O#.###.#.#.#.#.#
|
||||||
|
#.#.#.#...#.#.#...#.....#.......#...#...#.#.....#...#.#.#.#.#.#.....#.#.....#.#.......#.#.#.#...#.....#.#...#...#.....#...#.#O#...#...#.#...#
|
||||||
|
#.#.#.#.#.###.#.#####.#.###.#############.#.#####.#.#.#.#.#.#.#.###.#.#.#.###.#.#####.#.#.###.#.#.#####.###.#.#.#.###.#####.#O###.#####.###.#
|
||||||
|
#.#.#...#...#.........#.....#.....#.....#.#.#.....#.#...#.#.#...#.....#.#.#...#.......#.#.....#...#OOO#.....#.#...#.#.....#.#OOO#.........#.#
|
||||||
|
#.###.#.###.#.###.#.#########.###.#.#####.#.#.#####.#####.#.#.#.#######.#.#.###.#######.###########O#O#######.#####.#####.#.###O#########.#.#
|
||||||
|
#...#.#.#...#.#...#...#.........#.#.......#.#.#...#.......#.#.#.#.....#.#.#.#.#.......#...........#O#O#.#.......#OOO....#.#.#OOO#.......#.#.#
|
||||||
|
#.#.#.#.#.###.#####.#.#.#########.#.###.###.###.#.###.###.#.#.#.#.###.#.#.#.#.#######.#.#########.#O#O#.#.#.#####O#O###.#.#.#O###.#####.#.#.#
|
||||||
|
#.#.#.#.#.#.......#.#.....#.......#.......#.....#.#...#...#.#.#...#...#...#.#...........#.......#.#O#O..#.#..OOOOO#O#...#.#.#OOO#.....#.#...#
|
||||||
|
#.#.###.#.#######.#########.#.#####.#######.#####.#.#.#.###.#.#.###.###.###.#.###########.#.#.#.#.#O#O###.###O#.###O#.###.#.###O#####.#.#####
|
||||||
|
#.#.#...#.....#.......#.....#...#...#.......#...#...#.#.#.#...#.#.#.....#.....#.#...........#OOOOOOO#OOOOOOOOO#.#OOO#...#.#.#OOO#.....#.#...#
|
||||||
|
#.#.#.#.#####.#######.#.#####.#.#####.#.#.###.#.#####.#.#.#.###.#.#######.###.#.#.###########O#######.#####.#O#.#O#O#.#.#.#.#O###.#######.#.#
|
||||||
|
#.#.#.......#.....#.....#.....#.....#.#.....#.#...#...#.#...#.#.....#.#...#.....#...#.....#OOO#.....#.#.....#O#..O#O....#...#OOO#.#.......#.#
|
||||||
|
#.#.#.###.#.###.#.#######.#########.#.#######.###.#####.#.###.#####.#.#.###########.#####.#O###.###.#.#.###.#O###O#O###.#######O#.#.#######.#
|
||||||
|
#...#.#.#.#.#...#.#...#...#.#.....#...#...#...#.#...#...#.#...#.....#.#.#...........#.....#OOO#.#.#...#.#...#OOOOO#OOO#...#...#O#.#.#.....#.#
|
||||||
|
#.###.#.#.###.#.#.#.#.#.###.#.###.#####.###.###.###.#.###.#.###.#####.#.#.#########.#.#####.#O#.#.#####.#.#####.#####O###.#.###O#.#.#.###.#.#
|
||||||
|
#...#.#.#...#.#.#...#...#.....#.#.....#...#.#.....#.#.#.#.#.........#.#.......#OOO#...#OOO#.#O#.#...#...#...#...#...#O#.....#OOO#...#.#...#.#
|
||||||
|
###.#.#.###.#.#.###########.###.#####.#.#.#.#.#.###.#.#.#.#########.#.#########O#O#.###O#O###O#.#.#.###.###.#.#####.#O#######O###.#####.#.#.#
|
||||||
|
#...#.#...#...#.....#.....#.........#...#.#.#.#.......#...#.......#...#OOOOOOOOO#O#.#OOO#OOO#O#.#.#.....#.#...#.....#OOOOO..#O#.#.#...#.#.#.#
|
||||||
|
#.#.#.###.#####.###.###.#.#####.#########.#.###########.###.#####.###.#O#########O###O#####O#O#.#.#####.#.#####.###.#####O#.#O#.#.#.#.#.###.#
|
||||||
|
#...#.....#...#.#.#.#...#.#.#...#.........#.#.......#.....#.#.....#...#OOO#......OOOOO#....OOO#...#...#.........#.#.....#O..#O#.....#...#...#
|
||||||
|
#.#.#####.#.#.#.#.#.#.###.#.#.###.#######.#.#.#####.#####.#.#.#####.#####O#.###.#######.#######.#.###.###########.#.###.#O###O###########.#.#
|
||||||
|
#...#.....#.#.#.#.#...#...#.#.#...#...#.#.#.#.#...#.....#...#.#...#.#OOOOO#.....#...#...#.......#...#.......#.......#...#OOOOO#...#.....#.#.#
|
||||||
|
###.###.###.#.#.#.#####.###.#.#.###.#.#.#.#.#.#.###.#.#.#####.#.#.#.#O#.#####.#.#.#.#####.#########.#.#####.#.#####.#.#########.#.#.###.#.#.#
|
||||||
|
#.#...#.#.#.#...#.....#.#.....#.....#...#.#.....#...#.#...#.......#.#O#.#.....#.#.#.......#.#.......#.....#.#.#...#.#.#...#.....#...#.#.#.#.#
|
||||||
|
#.#.#.#.#.#.#####.#.###.#######.#.#.#.#.#.#####.#.#.#.###.#######.#.#O###.#####.#.#########.#.###.#######.#.#.###.#.#.#.#.###.#######.#.#.#.#
|
||||||
|
#.....#...#.....#.#.#...#.....#.#.#.#...#.......#.#.#...#...#...#.#.#O#.....#...#.......#...#.#.#.....#...#.#.....#...#.#...#.....#.......#.#
|
||||||
|
#.#.#####.#####.#.###.###.###.#.#.#.#########.###.#.#######.#.#.#.###O#.#####.#########.#.###.#.#####.#.###.#.#.#######.###.#.###.#########.#
|
||||||
|
#.....#...#...#.#...#.#.....#.....#.......#...#...#.........#.#.#...#O#.#.#...#.......#.#...#.......#.#...#.#.#.........#.#.#.#.#.....#.....#
|
||||||
|
#####.###.###.#.###.#.#.###.#####.#####.###.###.#############.#####.#O#.#.#.###.#.#####.#.#.###.#####.#####.#.#####.#.###.#.#.#.#####.###.###
|
||||||
|
#...#...#.....#.....#.#.#...#...#.....#...#.#...#.....#OOOOOOOOOOO#.#O#...........#...#.#.#.....#.....#.....#.....#.#.#.....#...#...#...#...#
|
||||||
|
#.#.###.#########.#.#.###.###.###.###.###.#.#.#####.#.#O#########O#.#O###.#######.#.#.#.#.#######.###.#.#.#.###.#.###.#.#####.###.#.#.#.###.#
|
||||||
|
#.#...#...........#.#.#...#.......#.....#.#.#.....#.#.#OOO#...#.#O#.#O#...#.....#.#.#...#.......#.#...#.#.#.....#.....#.#...#.#...#.#.#.#.#.#
|
||||||
|
#.#.###############.#.#.###.#######.###.#.#.#####.#.#####O#.#.#.#O#.#O#.#.#.###.#.#.#####.###.###.#.###.#.#.###.#######.#.#.#.#.###.###.#.#.#
|
||||||
|
#.#.#OOOOO..#OOOOO#...#...#.......#OOO#...#.......#.....#O..#...#OOOOO#.#...#...#.#.......#.#.#...#.#...#.#...#.#.....#.....#.#.............#
|
||||||
|
#.###O###O###O###O#.#####.#######.#O#O#########.#.#.#.###O###.#.#######.#.#.#.###.#######.#.#.#.#####.###.###.###.#.#######.#.#.#########.#.#
|
||||||
|
#OOO#O#.#OOOOO..#O#.#...#...#...#..O#OOOOOOO#...#.#.#....O..#.#.#.......#.#.#.#...#...#...#...#...#.....#.#...#...#.......#.#.#.....#...#...#
|
||||||
|
#O#O#O#.#########O#.#.#.###.#.#####O#######O#.###.#.#.#.#O#.#.#.#.#######.#.#.#.###.#.#.#########.#.#####.#.#.#.#####.#####.#.#####.#.#.#.###
|
||||||
|
#O#O#OOOOO#...#..OOOOOOOOOOOOOOOOO#OOOOO#.#O#.#.#.#...#.#O#...#.#...#.....#.#.#.....#...#.......#.....#...#.#.#.#...................#.#.#...#
|
||||||
|
#O#O#####O#.###.#.###.#######.#.#O#####O#.#O#.#.#.#.#.#.#O#.###.###.#######.#.#############.###.#######.###.#.#.###.#.#.#.#.#####.#####.###.#
|
||||||
|
#O#OOOOOOO..#...#.#...#.......#.#O....#OOO#O#...#.#.#...#O..#...#...#.......#.........#...#.#...........#...#.#.....#.#.#...#...#.#.....#...#
|
||||||
|
#O###########.###.#.#.#.###.###.#O#.#####O#O###.#.###.###O###.###.###.#######.#######.#.#.#.#############.#####.#####.#.#####.#.#.#.#.###.###
|
||||||
|
#OOO#OOO#.#...#...#.#.#...#.#...#O#.#OOOOO#O#...#...#....O......#.....#.......#...#...#.#.#...#...........#.....#.....#.#.....#...#.#...#.#.#
|
||||||
|
###O#O#O#.#.###.###.#.###.#.#.###O#.#O#####O#.#####.#.###O#############.#.#.###.#.#.###.#.###.#######.#####.#####.###.#.#.###.#####.###.#.#.#
|
||||||
|
#.#OOO#O..#.#.#.#...#.#...#...#..O#.#O....#O#...#.#.#...#O..#.....#.....#.#.#...#.#.....#...#.......#.#.....#...#.#...#.#...#.#...#.#.#.#...#
|
||||||
|
#.#####O###.#.#.#.###.#.#######.#O###O#####O###.#.#.#####O#.#.#.###.#####.#.#.###.#########.#.#####.#.#.#####.###.#.###.###.#.#.#.#.#.#.###.#
|
||||||
|
#OOOOO#O#...#...#.#.#...#.....#..O#OOO#....OOOOOOOOOOOOO#O#...........................#...#.#.#.....#.#.#.....#...#.#...#...#.#.#.#.#.#.....#
|
||||||
|
#O###O#O#.#######.#.#######.#.###O#O###.#########.#.#.#O#O#######.###.#.###.###.#####.#.#.#.#.#.#####.#.#####.#.#####.#######.#.#.#.#.#######
|
||||||
|
#O..#OOO#...................#...#OOO..#...........#...#OOO......#.....#.............#...#.......#.............#...............#.#...........#
|
||||||
|
#############################################################################################################################################
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
from collections import namedtuple
|
||||||
|
from math import sqrt
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
Point = namedtuple('Point', ['y', 'x'])
|
||||||
|
Node = namedtuple('Node', ['p', 'd'])
|
||||||
|
|
||||||
|
# set up inputs
|
||||||
|
text = Path('input').read_text('utf-8')
|
||||||
|
board_lines = text.splitlines()
|
||||||
|
width = len(board_lines[0])
|
||||||
|
board = list(map(list, board_lines))
|
||||||
|
start, end = Point(*divmod(text.find('S'), width + 1)), Point(*divmod(text.find('E'), width + 1))
|
||||||
|
|
||||||
|
# simple cost heuristic based on distance to end node
|
||||||
|
def cost_heuristic(p: Point) -> float:
|
||||||
|
return sqrt((p.x - end.x) ** 2 + (p.y - end.y) ** 2)
|
||||||
|
|
||||||
|
# walks path backwards, scans for nodes with incoming paths of equal cost, and traverses all recursively
|
||||||
|
def equal_cost_backtrace(parent: dict, node_cost: dict, current: Node) -> set[Point]:
|
||||||
|
last_direction = current.d
|
||||||
|
|
||||||
|
trace = {current.p}
|
||||||
|
while current := parent.get(current):
|
||||||
|
trace.add(current.p)
|
||||||
|
for d in map(lambda o: (current.d + o) & 3, [1, -1]):
|
||||||
|
test = Node(current.p, d)
|
||||||
|
if last_direction != current.d and (node_cost.get(test, 0) - node_cost[current]) == 1000:
|
||||||
|
trace.update(equal_cost_backtrace(parent, node_cost, parent.get(test)))
|
||||||
|
|
||||||
|
last_direction = current.d
|
||||||
|
|
||||||
|
return trace
|
||||||
|
|
||||||
|
# simple A star
|
||||||
|
def a_star() -> tuple[int, int]:
|
||||||
|
t_start = Node(start, 0)
|
||||||
|
|
||||||
|
pending: set[Node] = {t_start}
|
||||||
|
parent: dict[Node, Node] = {}
|
||||||
|
node_cost: dict[Node, float] = {t_start: 0.0}
|
||||||
|
total_cost: dict[Node, float] = {t_start: cost_heuristic(t_start.p)}
|
||||||
|
|
||||||
|
while len(pending):
|
||||||
|
current = min(pending, key=lambda t: total_cost[t])
|
||||||
|
|
||||||
|
if current.p == end:
|
||||||
|
return int(node_cost[current]), len(equal_cost_backtrace(parent, node_cost, current))
|
||||||
|
|
||||||
|
pending.remove(current)
|
||||||
|
|
||||||
|
# scan in all directions
|
||||||
|
for i, vector in enumerate([(0, 1), (1, 0), (0, -1), (-1, 0)]):
|
||||||
|
neighbor = Node(Point(current.p.y + vector[0], current.p.x + vector[1]), i)
|
||||||
|
if board[neighbor.p.y][neighbor.p.x] == '#':
|
||||||
|
continue
|
||||||
|
|
||||||
|
# assign new cost based on rotation and step
|
||||||
|
new_cost = node_cost[current] + [0, 1000, 2000, 1000][(i - current.d) & 3] + 1
|
||||||
|
if new_cost >= node_cost.get(neighbor, 1e13):
|
||||||
|
continue
|
||||||
|
|
||||||
|
parent[neighbor] = current
|
||||||
|
node_cost[neighbor] = new_cost
|
||||||
|
total_cost[neighbor] = new_cost + cost_heuristic(neighbor.p)
|
||||||
|
|
||||||
|
if neighbor in pending:
|
||||||
|
continue
|
||||||
|
|
||||||
|
pending.add(neighbor)
|
||||||
|
|
||||||
|
return 0, 0
|
||||||
|
|
||||||
|
|
||||||
|
lowest_cost, nodes = a_star()
|
||||||
|
|
||||||
|
print("Part 1:", lowest_cost)
|
||||||
|
print("Part 2:", nodes)
|
||||||
Reference in new issue
Block a user