Skip to content

Commit da2f8fc

Browse files
committed
Solution 2015-14 (Reindeer Olympics)
1 parent 067bf84 commit da2f8fc

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package de.ronny_h.aoc.year2015.day14
2+
3+
import de.ronny_h.aoc.AdventOfCode
4+
import kotlin.math.min
5+
6+
fun main() = ReindeerOlympics().run(2660, 1256)
7+
8+
class ReindeerOlympics : AdventOfCode<Int>(2015, 14) {
9+
override fun part1(input: List<String>): Int = input.parse().maxReindeerDistanceIn(2503)
10+
override fun part2(input: List<String>): Int = input.parse().pointsOfWinnerIn(2503)
11+
}
12+
13+
fun List<Reindeer>.maxReindeerDistanceIn(secondsTotal: Int) = map { it.reindeerDistanceIn(secondsTotal) }.max()
14+
15+
fun List<Reindeer>.pointsOfWinnerIn(secondsTotal: Int): Int {
16+
val reindeerPoints = MutableList(size) { 0 }
17+
for (seconds in 1..secondsTotal) {
18+
val distances = map { it.reindeerDistanceIn(seconds) }.withIndex()
19+
val leaderDistance = distances.maxOf { it.value }
20+
val leaders = distances.filter { it.value == leaderDistance }
21+
leaders.forEach {
22+
reindeerPoints[it.index]++
23+
}
24+
}
25+
return reindeerPoints.max()
26+
}
27+
28+
private fun Reindeer.reindeerDistanceIn(secondsTotal: Int): Int {
29+
val cycleDuration = flyDuration + restDuration
30+
val cycles = secondsTotal / cycleDuration
31+
val remainingFlyDuration = min(secondsTotal - (cycleDuration * cycles), flyDuration)
32+
return speed * (flyDuration * cycles + remainingFlyDuration)
33+
}
34+
35+
data class Reindeer(val speed: Int, val flyDuration: Int, val restDuration: Int)
36+
37+
fun List<String>.parse() = map {
38+
val (speed, flyDuration, restDuration) = it
39+
.substringAfter(" can fly ")
40+
.substringBeforeLast(" seconds.")
41+
.split(" km/s for ", " seconds, but then must rest for ")
42+
Reindeer(speed.toInt(), flyDuration.toInt(), restDuration.toInt())
43+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package de.ronny_h.aoc.year2015.day14
2+
3+
import io.kotest.core.spec.style.StringSpec
4+
import io.kotest.matchers.shouldBe
5+
6+
class ReindeerOlympicsTest : StringSpec({
7+
8+
val input = listOf(
9+
"Comet can fly 14 km/s for 10 seconds, but then must rest for 127 seconds.",
10+
"Dancer can fly 16 km/s for 11 seconds, but then must rest for 162 seconds.",
11+
)
12+
val parsedInput = listOf(
13+
Reindeer(14, 10, 127),
14+
Reindeer(16, 11, 162),
15+
)
16+
17+
"input can be parsed" {
18+
input.parse() shouldBe parsedInput
19+
}
20+
21+
"part 1: max Reindeer distance in 1000 seconds" {
22+
parsedInput.maxReindeerDistanceIn(1000) shouldBe 1120
23+
}
24+
25+
"part 2: points of the winner in 1000 seconds" {
26+
parsedInput.pointsOfWinnerIn(1000) shouldBe 689
27+
}
28+
})

0 commit comments

Comments
 (0)