Skip to content

Commit

Permalink
2024 - Day 20 - part 1 & 2
Browse files Browse the repository at this point in the history
  • Loading branch information
fmmr committed Dec 20, 2024
1 parent 44861c9 commit 41d14d8
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 16 deletions.
82 changes: 73 additions & 9 deletions src/main/kotlin/no/rodland/advent_2024/Day20.kt
Original file line number Diff line number Diff line change
@@ -1,26 +1,90 @@
package no.rodland.advent_2024

import no.rodland.advent.Day
import no.rodland.advent.*

// template generated: 20/12/2024
// Fredrik Rødland 2024

class Day20(val input: List<String>) : Day<Long, Long, List<String>> {
class Day20(val input: List<String>, private val limit: Int = 0, private val limitTestPart2: Int = limit) : Day<Int, Int, Pair<Array<CharArray>, Pair<Pos, Pos>>> {

private val parsed = input.parse()
private val racetrack: Cave = parsed.first
private val start = parsed.second.first
private val end = parsed.second.second

override fun partOne(): Long {
return 2
override fun partOne(): Int {
return solve(2, limit)
}

override fun partTwo(): Long {
return 2
override fun partTwo(): Int {
return solve(20, limitTestPart2)
}

override fun List<String>.parse(): List<String> {
return map { line ->
line
private fun solve(maxDistance: Int, lim: Int): Int {
val shortestPath = bfs(start, end)
val size = shortestPath.size
val fromStart = shortestPath.mapIndexed { idx, pos -> pos to idx }.toMap()
val toEnd = shortestPath.mapIndexed { idx, pos -> pos to size - idx }.toMap()
return shortestPath.asSequence().flatMapIndexed() { idx, from ->
shortestPath
.subList(idx + 1, shortestPath.size)
.mapNotNull { to ->
val manhattanDistance = from.manhattanDistance(to)
if (manhattanDistance in 2..maxDistance) {
manhattanDistance to to
} else {
null
}
}
.map { to ->
size - (fromStart[from]!! + to.first + toEnd[to.second]!!)
}.filter { it > 0 }
}
.groupBy { it }
.map { it.value.size to it.key }
.filter { it.second >= lim }
.sortedBy { it.second }
.sumOf { it.first }
}


private tailrec fun bfs(
start: Pos,
end: Pos,
queue: ArrayDeque<List<Pos>> = ArrayDeque(listOf(listOf(start))),
visited: MutableSet<Pos> = mutableSetOf(start)
): List<Pos> {
if (queue.isEmpty()) return emptyList()
// Dequeue the current path
val path = queue.removeFirst()
val current = path.last()

// Check if we reached the end position
if (current == end) return path
current.neighbourCellsUDLR()
.filter { it !in visited }
.filter { it in racetrack }
.filter { racetrack[it] != '#' }
.forEach { neighbor ->
visited.add(neighbor)
queue.add(path + neighbor) // Enqueue the new path
}
// Recursive call with the updated queue and visited set
return bfs(start, end, queue, visited)
}

override fun List<String>.parse(): Pair<Array<CharArray>, Pair<Pos, Pos>> {
var start = Pos(0, 0)
var end = Pos(0, 0)
return this.mapIndexed { y, line ->
line.mapIndexed { x, c ->
when (c) {
'S' -> start = Pos(x, y)
'E' -> end = Pos(x, y)
}
c
}.toCharArray()
}.toTypedArray<CharArray>() to (start to end)
}

override val day = "20".toInt()
Expand Down
16 changes: 9 additions & 7 deletions src/test/kotlin/no/rodland/advent_2024/Day20Test.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,22 @@ internal class Day20Test {
private val data20 = "2024/input_20.txt".readFile()
private val test20 = "2024/input_20_test.txt".readFile()

private val resultTestOne = 2L
private val resultTestTwo = 2L
private val resultOne = 2L
private val resultTwo = 2L
private val resultTestOne = 44
private val resultTestTwo = 285
private val resultOne = 1502
private val resultTwo = 1028136

val test = defaultTestSuiteParseOnInit(
Day20(data20),
Day20(test20),
Day20(data20, 100),
Day20(test20, 0, 50),
resultTestOne,
resultOne,
resultTestTwo,
resultTwo,
{ Day20(data20) },
{ Day20(data20, 100) },
{ Day20(test20) },
numTestPart1 = 1,
numTestPart2 = 1,
)

@Nested
Expand Down
15 changes: 15 additions & 0 deletions src/test/resources/2024/input_20_test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
###############
#...#...#.....#
#.#.#.#.#.###.#
#S#...#.#.#...#
#######.#.#.###
#######.#.#...#
#######.#.###.#
###..E#...#...#
###.#######.###
#...###...#...#
#.#####.#.###.#
#.#...#.#.#...#
#.#.#.#.#.#.###
#...#...#...###
###############

0 comments on commit 41d14d8

Please sign in to comment.