Skip to content

Commit da6073c

Browse files
committed
ShortestPath: Instead of passing the goal node, pass a function
The function `isGoal` is a predicate stating if the current node equals the goal node.
1 parent da76ce3 commit da6073c

File tree

4 files changed

+11
-11
lines changed

4 files changed

+11
-11
lines changed

src/main/kotlin/de/ronny_h/aoc/extensions/ShortestPath.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ private const val LARGE_VALUE = MAX_VALUE / 2
2323
/**
2424
* A* finds a path from `start` to `goal`.
2525
* @param start the start node
26-
* @param goal the goal node
26+
* @param isGoal predicate deciding if a node is a goal
2727
* @param neighbors is a function that returns the list of neighbours for a given node.
2828
* @param d is the distance/cost function. d(m,n) provides the distance (or cost) to reach node n from node m.
2929
* @param h is the heuristic function. h(n) estimates the cost to reach goal from node n.
3030
*/
31-
fun <N> aStar(start: N, goal: N, neighbors: (N) -> List<N>, d: (N, N) -> Int, h: (N) -> Int,
31+
fun <N> aStar(start: N, isGoal: N.() -> Boolean, neighbors: (N) -> List<N>, d: (N, N) -> Int, h: (N) -> Int,
3232
printIt: (visited: Set<N>, current: N, additionalInfo: () -> String) -> Unit = {_, _, _ -> }): ShortestPath<N> {
3333
// For node n, fScore[n] := gScore[n] + h(n). fScore[n] represents our current best guess as to
3434
// how cheap a path could be from start to finish if it goes through n.
@@ -53,7 +53,7 @@ fun <N> aStar(start: N, goal: N, neighbors: (N) -> List<N>, d: (N, N) -> Int, h:
5353
while (openSet.isNotEmpty()) {
5454
// This operation can occur in O(Log(N)) time if openSet is a min-heap or a priority queue
5555
val current = openSet.peek()
56-
if (current == goal) {
56+
if (isGoal(current)) {
5757
return ShortestPath(reconstructPath(cameFrom, current), gScore.getValue(current))
5858
}
5959

@@ -78,5 +78,5 @@ fun <N> aStar(start: N, goal: N, neighbors: (N) -> List<N>, d: (N, N) -> Int, h:
7878
}
7979

8080
// Open set is empty but goal was never reached
81-
error("No path found from $start to $goal")
81+
error("No path found from $start to goal")
8282
}

src/main/kotlin/de/ronny_h/aoc/year24/day18/RAMRun.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,6 @@ private class MemorySpace(width: Int, corrupted: List<Coordinates>) : Grid<Char>
5858

5959
val h: (Coordinates) -> Int = { it taxiDistanceTo goal }
6060

61-
return aStar(start, goal, neighbours, d, h)
61+
return aStar(start, { this == goal }, neighbours, d, h)
6262
}
6363
}

src/main/kotlin/de/ronny_h/aoc/year24/day20/RaceCondition.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ private class RaceTrack(input: List<String>) : Grid<Char>(input, '#') {
4242

4343
val h: (Coordinates) -> Int = { it taxiDistanceTo goal }
4444

45-
return aStar(start, goal, neighbours, d, h)
45+
return aStar(start, { this == goal }, neighbours, d, h)
4646
}
4747

4848
fun countAllShortcutsSavingAtLeast(minToSave: Int, shortcutMaxLength: Int): Int {

src/test/kotlin/de/ronny_h/aoc/extensions/ShortestPathTest.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class ShortestPathTest : StringSpec({
6060
1
6161
)
6262
)
63-
aStar(start, goal, neighbours, d, h) shouldBe ShortestPath(listOf(start, goal), 1)
63+
aStar(start, goal::positionEquals, neighbours, d, h) shouldBe ShortestPath(listOf(start, goal), 1)
6464
}
6565

6666
"With 2 different nodes between start and goal, the shorter path is taken" {
@@ -88,7 +88,7 @@ class ShortestPathTest : StringSpec({
8888

8989
aStarAllPaths(start, goal::positionEquals, { n -> neighbours.getValue(n) }, d, h) shouldBe
9090
listOf(ShortestPath(listOf(start, a, goal), 10))
91-
aStar(start, goal, { n -> neighbours.getValue(n) }, d, h) shouldBe
91+
aStar(start, goal::positionEquals, { n -> neighbours.getValue(n) }, d, h) shouldBe
9292
ShortestPath(listOf(start, a, goal), 10)
9393
}
9494

@@ -114,7 +114,7 @@ class ShortestPathTest : StringSpec({
114114

115115
aStarAllPaths(start, goal::positionEquals, { n -> neighbours.getValue(n) }, d, h) shouldBe
116116
listOf(ShortestPath(listOf(start, a, goal), 9))
117-
aStar(start, goal, { n -> neighbours.getValue(n) }, d, h) shouldBe
117+
aStar(start, goal::positionEquals, { n -> neighbours.getValue(n) }, d, h) shouldBe
118118
ShortestPath(listOf(start, a, goal), 9)
119119
}
120120

@@ -144,7 +144,7 @@ class ShortestPathTest : StringSpec({
144144

145145
aStarAllPaths(start, goal::positionEquals, { n -> neighbours.getValue(n) }, d, h) shouldBe
146146
listOf(ShortestPath(listOf(start, a, goal), 9))
147-
aStar(start, goal, { n -> neighbours.getValue(n) }, d, h) shouldBe
147+
aStar(start, goal::positionEquals, { n -> neighbours.getValue(n) }, d, h) shouldBe
148148
ShortestPath(listOf(start, a, goal), 9)
149149
}
150150

@@ -173,7 +173,7 @@ class ShortestPathTest : StringSpec({
173173

174174
aStarAllPaths(start, goal::positionEquals, { n -> neighbours.getValue(n) }, d, h) shouldBe
175175
listOf(ShortestPath(listOf(start, a, b, goal), 9))
176-
aStar(start, goal, { n -> neighbours.getValue(n) }, d, h) shouldBe
176+
aStar(start, goal::positionEquals, { n -> neighbours.getValue(n) }, d, h) shouldBe
177177
ShortestPath(listOf(start, a, b, goal), 9)
178178
}
179179
})

0 commit comments

Comments
 (0)