11package de.ronny_h.aoc.year2024.day20
22
33import de.ronny_h.aoc.AdventOfCode
4+ import de.ronny_h.aoc.extensions.animation.*
45import de.ronny_h.aoc.extensions.graphs.shortestpath.ShortestPath
56import de.ronny_h.aoc.extensions.graphs.shortestpath.aStar
67import de.ronny_h.aoc.extensions.grids.Coordinates
78import de.ronny_h.aoc.extensions.grids.Direction
89import de.ronny_h.aoc.extensions.grids.Grid
10+ import de.ronny_h.aoc.year2024.day20.RaceTrack.Companion.EMPTY
11+ import de.ronny_h.aoc.year2024.day20.RaceTrack.Companion.GOAL
12+ import de.ronny_h.aoc.year2024.day20.RaceTrack.Companion.SHORTCUT_START
13+ import de.ronny_h.aoc.year2024.day20.RaceTrack.Companion.START
14+ import de.ronny_h.aoc.year2024.day20.RaceTrack.Companion.VISITED
15+ import de.ronny_h.aoc.year2024.day20.RaceTrack.Companion.WALL
16+ import java.awt.Color.red
917
1018fun main () = RaceCondition ().run (1438 , 1026446 )
1119
1220class RaceCondition : AdventOfCode <Int >(2024 , 20 ) {
1321 fun part1 (input : List <String >, minPicosecondsSaved : Int , shortcutMaxLength : Int ): Int {
1422 val track = RaceTrack (input)
15- track.printGrid()
16- return track.countAllShortcutsSavingAtLeast(minPicosecondsSaved, shortcutMaxLength)
23+ // track.recorder = AnimationRecorder()
24+ // track.printGrid()
25+ val result = track.countAllShortcutsSavingAtLeast(minPicosecondsSaved, shortcutMaxLength)
26+ track.recorder?.saveTo(
27+ " animations/$year -${paddedDay()} _${javaClass.simpleName} .gif" ,
28+ mapOf (
29+ START to green,
30+ GOAL to yellow,
31+ WALL to lightGrey,
32+ EMPTY to gray,
33+ VISITED to lightBlue,
34+ SHORTCUT_START to red,
35+ ),
36+ )
37+ return result
1738 }
1839
1940 fun part1Small (input : List <String >) = part1(input, 10 , 2 )
@@ -24,19 +45,28 @@ class RaceCondition : AdventOfCode<Int>(2024, 20) {
2445
2546}
2647
27- private class RaceTrack (input : List <String >) : Grid<Char>(input, ' #' ) {
28- private val wall = nullElement
48+ private class RaceTrack (input : List <String >) : Grid<Char>(input, WALL ) {
49+
50+ companion object {
51+ const val START = ' S'
52+ const val GOAL = ' E'
53+ const val WALL = ' #'
54+ const val EMPTY = ' .'
55+ const val VISITED = ' o'
56+ const val SHORTCUT_START = ' x'
57+ }
58+
2959 override fun Char.toElementType (): Char = this
3060
31- private val start = find(' S ' )
32- private val goal = find(' E ' )
61+ private val start = find(START )
62+ private val goal = find(GOAL )
3363
3464 fun shortestPath (): ShortestPath <Coordinates > {
3565 val neighbours: (Coordinates ) -> List <Coordinates > = { node ->
3666 Direction
3767 .entries
3868 .map { node + it }
39- .filter { get(node) != wall }
69+ .filter { get(node) != WALL }
4070 }
4171
4272 val d: (Coordinates , Coordinates ) -> Int = { _, _ ->
@@ -46,7 +76,12 @@ private class RaceTrack(input: List<String>) : Grid<Char>(input, '#') {
4676
4777 val h: (Coordinates ) -> Int = { it taxiDistanceTo goal }
4878
49- return aStar(start, { this == goal }, neighbours, d, h)
79+ return aStar(
80+ start, { this == goal }, neighbours, d, h,
81+ printIt = { visited, _, _ ->
82+ recorder?.record(toString(visited.filter { get(it) == EMPTY }.toSet(), VISITED ))
83+ }
84+ )
5085 }
5186
5287 fun countAllShortcutsSavingAtLeast (minToSave : Int , shortcutMaxLength : Int ): Int {
@@ -61,11 +96,14 @@ private class RaceTrack(input: List<String>) : Grid<Char>(input, '#') {
6196 fun Coordinates.isShorterToGoalThan (position : Coordinates ): Boolean =
6297 distances.getValue(this ) + (this taxiDistanceTo position) <= distances.getValue(position) - minToSave
6398
64- return shortestPath.path.flatMap { position ->
99+ val shortcutStartPositions = shortestPath.path.flatMap { position ->
65100 shortestPath
66101 .path
67- .filter { it.isInShortcutRangeFrom(position) }
68- .filter { it.isShorterToGoalThan(position) }
69- }.size
102+ .filter { position.isInShortcutRangeFrom(it) }
103+ .filter { position.isShorterToGoalThan(it) }
104+ }
105+ recorder?.recordLastFrameWithOverrides(shortcutStartPositions, SHORTCUT_START )
106+ recorder?.repeatLast(2 , 3 )
107+ return shortcutStartPositions.size
70108 }
71109}
0 commit comments