@@ -25,70 +25,50 @@ data class Tile(
2525 var endDistance : Long? ,
2626)
2727
28- val possibleJumps =
29- listOf (
30- IVec2 (- 2 , 0 ),
31- IVec2 (2 , 0 ),
32- IVec2 (0 , 2 ),
33- IVec2 (0 , - 2 ),
34- IVec2 (1 , 1 ),
35- IVec2 (- 1 , 1 ),
36- IVec2 (- 1 , - 1 ),
37- IVec2 (1 , - 1 ),
38- )
39-
4028suspend fun y2024day20part1 (
4129 input : Input ,
4230 atLeast : Int ,
4331): Long {
4432 logger.info(" year 2024 day 20 part 1" )
33+ val possibleJumps =
34+ listOf (
35+ IVec2 (- 2 , 0 ),
36+ IVec2 (2 , 0 ),
37+ IVec2 (0 , 2 ),
38+ IVec2 (0 , - 2 ),
39+ IVec2 (1 , 1 ),
40+ IVec2 (- 1 , 1 ),
41+ IVec2 (- 1 , - 1 ),
42+ IVec2 (1 , - 1 ),
43+ ).associateWith { 2 }
44+
45+ val grid = parseGrid(input)
46+ var (startPos: IVec2 , endPos: IVec2 ) = findStartAndEnd(grid)
4547
46- val grid =
47- input.grid {
48- when (it) {
49- ' #' -> Tile (WALL , null , null )
50- ' .' -> Tile (EMPTY , null , null )
51- ' S' -> Tile (START , null , null )
52- ' E' -> Tile (END , null , null )
53- else -> error(" unexpected tile $it " )
54- }
55- }
56- lateinit var startPos: IVec2
57- lateinit var endPos: IVec2
58- grid.allIVec2().forEach {
59- when (grid[it]?.type) {
60- START -> startPos = it
61- END -> endPos = it
62- else -> Unit
63- }
64- }
48+ floodStart(grid, startPos)
49+ floodEnd(grid, endPos)
50+
51+ val normalLength = grid[startPos]!! .endDistance!!
52+ logger.debug { " Normal length: $normalLength " }
53+ return countViableJumps(grid, possibleJumps, normalLength, atLeast).toLong()
54+ }
55+
56+ suspend fun y2024day20part2 (
57+ input : Input ,
58+ atLeast : Int ,
59+ ): Long {
60+ logger.info(" year 2024 day 20 part 2" )
61+ val grid = parseGrid(input)
62+ var (startPos: IVec2 , endPos: IVec2 ) = findStartAndEnd(grid)
6563
6664 floodStart(grid, startPos)
6765 floodEnd(grid, endPos)
6866
67+ val possibleJumps2 = buildPossibleJumps2()
68+
6969 val normalLength = grid[startPos]!! .endDistance!!
7070 logger.debug { " Normal length: $normalLength " }
71- return grid
72- .allIVec2()
73- .sumOf { pos ->
74- val startDistance = grid[pos]?.startDistance ? : return @sumOf 0
75-
76- possibleJumps.count { jump ->
77- val jumpPos = pos + jump
78- val endDistanceJump = grid[jumpPos]?.endDistance ? : return @count false
79-
80- val saved = normalLength - 2 - startDistance - endDistanceJump
81- if (pos.x == 7 && pos.y == 7 ) {
82- logger.debug { " $pos $jump $endDistanceJump $saved " }
83- }
84- if (saved >= atLeast) {
85- logger.info { " found jump $pos to $jumpPos saving $saved " }
86- true
87- } else {
88- false
89- }
90- }
91- }.toLong()
71+ return countViableJumps(grid, possibleJumps2, normalLength, atLeast).toLong()
9272}
9373
9474fun floodStart (
@@ -145,21 +125,18 @@ fun floodEnd(
145125 }
146126}
147127
148- suspend fun y2024day20part2 (
149- input : Input ,
150- atLeast : Int ,
151- ): Long {
152- logger.info(" year 2024 day 20 part 2" )
153- val grid =
154- input.grid {
155- when (it) {
156- ' #' -> Tile (WALL , null , null )
157- ' .' -> Tile (EMPTY , null , null )
158- ' S' -> Tile (START , null , null )
159- ' E' -> Tile (END , null , null )
160- else -> error(" unexpected tile $it " )
161- }
128+ private suspend fun parseGrid (input : Input ) =
129+ input.grid {
130+ when (it) {
131+ ' #' -> Tile (WALL , null , null )
132+ ' .' -> Tile (EMPTY , null , null )
133+ ' S' -> Tile (START , null , null )
134+ ' E' -> Tile (END , null , null )
135+ else -> error(" unexpected tile $it " )
162136 }
137+ }
138+
139+ private fun findStartAndEnd (grid : Grid <Tile >): Pair <IVec2 , IVec2 > {
163140 lateinit var startPos: IVec2
164141 lateinit var endPos: IVec2
165142 grid.allIVec2().forEach {
@@ -169,10 +146,34 @@ suspend fun y2024day20part2(
169146 else -> Unit
170147 }
171148 }
149+ return Pair (startPos, endPos)
150+ }
172151
173- floodStart(grid, startPos)
174- floodEnd(grid, endPos)
152+ private fun countViableJumps (
153+ grid : Grid <Tile >,
154+ possibleJumps2 : Map <IVec2 , Int >,
155+ normalLength : Long ,
156+ atLeast : Int ,
157+ ) = grid
158+ .allIVec2()
159+ .sumOf { pos ->
160+ val startDistance = grid[pos]?.startDistance ? : return @sumOf 0
161+
162+ possibleJumps2.count { jump ->
163+ val jumpPos = pos + jump.key
164+ val endDistanceJump = grid[jumpPos]?.endDistance ? : return @count false
165+
166+ val saved = normalLength - jump.value - startDistance - endDistanceJump
167+ if (saved >= atLeast) {
168+ logger.debug { " found jump $pos to $jumpPos saving $saved " }
169+ true
170+ } else {
171+ false
172+ }
173+ }
174+ }
175175
176+ private fun buildPossibleJumps2 (): MutableMap <IVec2 , Int > {
176177 val possibleJumps2 = mutableMapOf<IVec2 , Int >()
177178 possibleJumps2.put(IVec2 (0 , 0 ), 0 )
178179 var cost = 0
@@ -187,25 +188,5 @@ suspend fun y2024day20part2(
187188 }
188189 cost = nextCost
189190 }
190-
191- val normalLength = grid[startPos]!! .endDistance!!
192- logger.debug { " Normal length: $normalLength " }
193- return grid
194- .allIVec2()
195- .sumOf { pos ->
196- val startDistance = grid[pos]?.startDistance ? : return @sumOf 0
197-
198- possibleJumps2.count { jump ->
199- val jumpPos = pos + jump.key
200- val endDistanceJump = grid[jumpPos]?.endDistance ? : return @count false
201-
202- val saved = normalLength - jump.value - startDistance - endDistanceJump
203- if (saved >= atLeast) {
204- logger.debug { " found jump $pos to $jumpPos saving $saved " }
205- true
206- } else {
207- false
208- }
209- }
210- }.toLong()
191+ return possibleJumps2
211192}
0 commit comments