@@ -36,32 +36,50 @@ class Day6(val input: Input) : Puzzle {
36
36
data class PathResult (
37
37
val points : Set <Point >,
38
38
val loop : Boolean ,
39
+ val jumpTable : Map <Pair <Point , Dir >, Point >,
39
40
)
40
41
41
- private fun findPath (grid : Grid <Boolean >, start : Point ): PathResult {
42
+ private fun findPath (grid : Grid <Boolean >, start : Point , jumpTable : Map < Pair < Point , Dir >, Point > ? = null ): PathResult {
42
43
var cur = start
43
44
val visited = mutableSetOf<Point >()
44
45
val visitedWithDir = mutableSetOf<Pair <Point , Dir >>()
45
46
47
+ val computeNewJumpTable = jumpTable == null
48
+ val newJumpTable = mutableMapOf<Pair <Point , Dir >, Point > ()
49
+
50
+ var jumpStart: Point ? = null
46
51
var dir = 1
47
52
while (grid.withinBounds(cur.row, cur.col)) {
48
53
visited + = cur
49
54
if (! visitedWithDir.add(cur to directions[dir])) {
50
- return PathResult (visited, true )
55
+ return PathResult (visited, true , newJumpTable)
56
+ }
57
+
58
+ if (computeNewJumpTable) {
59
+ if (jumpStart == null ) {
60
+ jumpStart = cur
61
+ }
51
62
}
52
63
53
64
// Assumes no bad input that could lead to an infinite loop
54
65
while (true ) {
55
66
val d = directions[dir]
56
67
57
- val next = cur + d.toPoint()
68
+ val next = jumpTable?. let { it[ cur to d] } ? : (cur + d.toPoint() )
58
69
if (! grid.withinBounds(next.row, next.col)) {
59
70
cur = next
60
71
break
61
72
}
62
73
63
74
if (grid[next.row][next.col].value) {
64
75
// Obstacle, rotate
76
+ if (computeNewJumpTable) {
77
+ if (jumpStart != null && jumpStart != cur) {
78
+ newJumpTable[jumpStart to d] = cur
79
+ }
80
+ jumpStart = null
81
+ }
82
+
65
83
dir = (dir + 1 ) % 4
66
84
continue
67
85
}
@@ -71,7 +89,7 @@ class Day6(val input: Input) : Puzzle {
71
89
}
72
90
}
73
91
74
- return PathResult (visited, false )
92
+ return PathResult (visited, false , newJumpTable )
75
93
}
76
94
77
95
override fun solveLevel1 (): Any {
@@ -98,7 +116,10 @@ class Day6(val input: Input) : Puzzle {
98
116
}
99
117
100
118
grid[row][col].value = true
101
- val path = findPath(grid, guard)
119
+ val withJumpTable = normalPath.jumpTable.filterKeys { (start, _) ->
120
+ start.row != p.row && start.col != p.col
121
+ }
122
+ val path = findPath(grid, guard, withJumpTable)
102
123
if (path.loop) {
103
124
numLoops++
104
125
}
0 commit comments