Skip to content

Commit 01e08e7

Browse files
authored
Day 10 2024 (#269)
1 parent c1d2583 commit 01e08e7

File tree

4 files changed

+104
-0
lines changed

4 files changed

+104
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package me.peckb.aoc._2024.calendar.day10
2+
3+
import javax.inject.Inject
4+
import me.peckb.aoc.generators.InputGenerator.InputGeneratorFactory
5+
6+
class Day10 @Inject constructor(
7+
private val generatorFactory: InputGeneratorFactory,
8+
) {
9+
fun partOne(filename: String) = generatorFactory.forFile(filename).read { lines ->
10+
val (topoMap, trailHeads) = setup(lines)
11+
12+
fun dfs(location: Location) : Set<Location> {
13+
val myElevation = topoMap[location.y][location.x]
14+
if (myElevation == 9) return setOf(location)
15+
16+
return getNeighbors(location, topoMap).flatMap { dfs(it) }.toSet()
17+
}
18+
19+
trailHeads.sumOf { dfs(it).size }
20+
}
21+
22+
fun partTwo(filename: String) = generatorFactory.forFile(filename).read { lines ->
23+
val (topoMap, trailHeads) = setup(lines)
24+
25+
fun dfs(location: Location) : Int {
26+
val myElevation = topoMap[location.y][location.x]
27+
if (myElevation == 9) return 1
28+
29+
return getNeighbors(location, topoMap).sumOf { dfs(it) }
30+
}
31+
32+
trailHeads.sumOf { dfs(it) }
33+
}
34+
35+
private fun getNeighbors(location: Location, topoMap: MutableList<MutableList<Int>>) : List<Location> {
36+
val (y, x) = location
37+
38+
val n = Location(y-1, x)
39+
val e = Location(y, x+1)
40+
val s = Location(y+1, x)
41+
val w = Location(y, x-1)
42+
43+
val myElevation = topoMap[y][x]
44+
45+
return listOf(n, e, s, w)
46+
.filter { it.y in topoMap.indices && it.x in topoMap[it.y].indices }
47+
.filter { topoMap[it.y][it.x] == myElevation + 1 }
48+
}
49+
50+
private fun setup(lines: Sequence<String>): Pair<MutableList<MutableList<Int>>, MutableList<Location>> {
51+
val topoMap = mutableListOf<MutableList<Int>>()
52+
val trailHeads = mutableListOf<Location>()
53+
54+
lines.forEachIndexed { yIndex, line ->
55+
val row = mutableListOf<Int>()
56+
line.forEachIndexed { xIndex, c ->
57+
val elevation = c.digitToIntOrNull() ?: -1
58+
59+
if (elevation == 0) { trailHeads.add(Location(yIndex, xIndex)) }
60+
row.add(elevation)
61+
}
62+
topoMap.add(row)
63+
}
64+
65+
return topoMap to trailHeads
66+
}
67+
}
68+
69+
data class Location(val y: Int, val x: Int)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
## [Day 10: Hoof It](https://adventofcode.com/2024/day/10)

src/test/kotlin/me/peckb/aoc/_2024/TestDayComponent.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import me.peckb.aoc._2024.calendar.day06.Day06Test
99
import me.peckb.aoc._2024.calendar.day07.Day07Test
1010
import me.peckb.aoc._2024.calendar.day08.Day08Test
1111
import me.peckb.aoc._2024.calendar.day09.Day09Test
12+
import me.peckb.aoc._2024.calendar.day10.Day10Test
1213
import javax.inject.Singleton
1314
import me.peckb.aoc.DayComponent
1415
import me.peckb.aoc.InputModule
@@ -26,4 +27,5 @@ internal interface TestDayComponent : DayComponent {
2627
fun inject(day07Test: Day07Test)
2728
fun inject(day08Test: Day08Test)
2829
fun inject(day09Test: Day09Test)
30+
fun inject(day10Test: Day10Test)
2931
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package me.peckb.aoc._2024.calendar.day10
2+
3+
import javax.inject.Inject
4+
5+
import me.peckb.aoc._2024.DaggerTestDayComponent
6+
import org.junit.jupiter.api.Assertions.assertEquals
7+
import org.junit.jupiter.api.BeforeEach
8+
import org.junit.jupiter.api.Test
9+
10+
internal class Day10Test {
11+
@Inject
12+
lateinit var day10: Day10
13+
14+
@BeforeEach
15+
fun setup() {
16+
DaggerTestDayComponent.create().inject(this)
17+
}
18+
19+
@Test
20+
fun testDay10PartOne() {
21+
assertEquals(538, day10.partOne(DAY_10))
22+
}
23+
24+
@Test
25+
fun testDay10PartTwo() {
26+
assertEquals(1110, day10.partTwo(DAY_10))
27+
}
28+
29+
companion object {
30+
private const val DAY_10: String = "advent-of-code-input/2024/day10.input"
31+
}
32+
}

0 commit comments

Comments
 (0)