Skip to content

Commit a3f2c02

Browse files
committed
Day 10 complete with some refactoring.
1 parent dd2e6fb commit a3f2c02

File tree

5 files changed

+40
-52
lines changed

5 files changed

+40
-52
lines changed

src/main/kotlin/common/intpos2d/intpos2d.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,24 @@ operator fun Int.times(pos: IntPos2D): IntPos2D =
1616

1717
operator fun IntPos2D.times(factor: Int) =
1818
factor * this
19+
20+
enum class Direction(val delta: IntPos2D) {
21+
NORTH(IntPos2D(-1, 0)),
22+
EAST(IntPos2D(0, 1)),
23+
SOUTH(IntPos2D(1, 0)),
24+
WEST(IntPos2D(0, -1));
25+
26+
fun clockwise(): Direction = when (this) {
27+
NORTH -> EAST
28+
EAST -> SOUTH
29+
SOUTH -> WEST
30+
WEST -> NORTH
31+
}
32+
33+
fun counterClockwise(): Direction = when (this) {
34+
NORTH -> WEST
35+
WEST -> SOUTH
36+
SOUTH -> EAST
37+
EAST -> NORTH
38+
}
39+
}

src/main/kotlin/day06/day06.kt

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,6 @@ package day06
99
import common.aocreader.fetchAdventOfCodeInput
1010
import common.intpos2d.*
1111

12-
/**
13-
* The direction that the guard is facing and moves in.
14-
*/
15-
private enum class Direction(val delta: IntPos2D) {
16-
NORTH(IntPos2D(-1, 0)),
17-
SOUTH(IntPos2D(1, 0)),
18-
EAST(IntPos2D(0, 1)),
19-
WEST(IntPos2D(0, -1));
20-
21-
fun clockwise(): Direction = when (this) {
22-
NORTH -> EAST
23-
EAST -> SOUTH
24-
SOUTH -> WEST
25-
WEST -> NORTH
26-
}
27-
}
28-
2912
private typealias Orientation = Pair<Direction, IntPos2D>
3013

3114
private data class MapGrid(val rows: Int,

src/main/kotlin/day09/day09.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ fun answer2(input: String): BigInteger =
191191
fun main() {
192192
val input = fetchAdventOfCodeInput(2024, 9)
193193

194-
println("--- Day 9: Resonant Collinearity ---")
194+
println("--- Day 9: Disk Fragmenter ---")
195195

196196
// Part 1: 6384282079460
197197
println("Part 1: ${answer1(input)}")

src/main/kotlin/day10/day10.kt

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,80 +5,64 @@ package day10
55

66
import common.aocreader.fetchAdventOfCodeInput
77
import common.intpos2d.*
8-
import common.parsing.parseGrid
98

109
private typealias Trail = List<IntPos2D>
1110
private typealias Trails = Set<List<IntPos2D>>
1211

13-
private enum class Direction(val delta: IntPos2D) {
14-
NORTH(IntPos2D(-1, 0)),
15-
EAST(IntPos2D(0, 1)),
16-
SOUTH(IntPos2D(1, 0)),
17-
WEST(IntPos2D(0, -1)),
18-
}
19-
2012
private fun parse(input: String): List<List<Int>> =
2113
input.trim().lines()
22-
.map { line -> line.trim().toList().map { it.digitToInt() } }
14+
.map { line -> line.trim().toList().map { it.digitToIntOrNull() ?: -1 } }
2315

24-
private fun findTrailheads(grid: List<List<Int>>): Map<IntPos2D, Trails> {
16+
private fun findTrails(grid: List<List<Int>>): Map<IntPos2D, Trails> {
2517
val height = grid.size
2618
val width = grid[0].size
2719

28-
// Instead of going from zeros to nines, we go from nines to zeros
29-
// to count the number of trails to the peak.
30-
// Find the nines, i.e. the ending positions of the map.
31-
val nines = grid.flatMapIndexed { rowIdx, row ->
20+
val zeros = grid.flatMapIndexed { rowIdx, row ->
3221
row.mapIndexedNotNull { colIdx, height ->
33-
if (height == 9) IntPos2D(rowIdx, colIdx) else null
22+
if (height == 0) IntPos2D(rowIdx, colIdx) else null
3423
}
3524
}.toSet()
3625

37-
// We need to track the number of trails to each nine.
38-
val trails: MutableMap<IntPos2D, Trails> = mutableMapOf()
39-
4026
// For each 9, we want to find the trails that lead to the peak.
4127
fun aux(trailSoFar: Trail): Trails {
4228
val currentPos = trailSoFar.last()
4329
val (currY, currX) = currentPos
4430
val currHeight = grid[currY][currX]
45-
if (currHeight == 0) return setOf(trailSoFar)
31+
if (currHeight == 9) return setOf(trailSoFar)
4632

4733
// Try all the valid neighbours.
4834
val neighbours = Direction.entries
4935
.map { currentPos + it.delta }
5036
.filter { coords -> coords.first in 0 until height && coords.second in 0 until width }
51-
.filter { coords -> grid[coords.first][coords.second] == currHeight - 1 }
37+
.filter { coords -> grid[coords.first][coords.second] == currHeight + 1 }
5238
if (neighbours.isEmpty()) return emptySet()
5339

5440
return neighbours.flatMap { pos -> aux(trailSoFar + pos) }.toSet()
5541
}
5642

57-
nines.forEach { nine ->
58-
val allTrails = aux(listOf(nine))
59-
trails[nine] = allTrails
60-
}
61-
62-
return trails
43+
return zeros.associate { zero -> zero to aux(listOf(zero)) }
6344
}
6445

65-
fun countTrailheads(trails: Map<IntPos2D, Trails>): Int =
66-
trails.values.flatten().toSet().size
46+
private fun countTrailheads(trails: Map<IntPos2D, Trails>): Int =
47+
trails.values.sumOf { it.map { it.last() }.toSet().size }
48+
49+
private fun countTrails(trails: Map<IntPos2D, Trails>): Int =
50+
trails.values.sumOf { it.count() }
6751

6852
fun answer1(input: String): Int =
69-
parse(input).let(::findTrailheads).let(::countTrailheads)
53+
parse(input).let(::findTrails).let(::countTrailheads)
7054

7155
fun answer2(input: String): Int =
72-
TODO()
56+
parse(input).let(::findTrails).let(::countTrails)
7357

7458
fun main() {
7559
val input = fetchAdventOfCodeInput(2024, 10)
7660

77-
println("--- Day 10: Resonant Collinearity ---")
61+
println("--- Day 10: Hoof It ---")
7862

79-
// Part 1:
63+
// Part 1: 719
8064
println("Part 1: ${answer1(input)}")
8165

82-
// Part 2:
66+
// Part 2: 1530
8367
println("Part 2: ${answer2(input)}")
8468
}

src/test/kotlin/day10/day10.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ class Day10Test {
2727

2828
@Test
2929
fun `Problem 2 example`() =
30-
assertEquals(TODO(), answer2(input))
30+
assertEquals(81, answer2(input))
3131
}

0 commit comments

Comments
 (0)