-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReindeerOlympics.kt
60 lines (52 loc) · 1.88 KB
/
ReindeerOlympics.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package AoC2015.Day14
import java.nio.file.Files
import java.nio.file.Paths
import java.util.*
fun main(args: Array<String>) {
val reindeers = Files.readAllLines(Paths.get(args[0]))
.map { parseReindeer(it.split(" ")) }
val time = 2503
println(reindeers.map { reindeer -> reindeer.name to getDistance(time, reindeer) }
.maxBy { it.second }?.second)
println(reindeersResults(reindeers, time))
}
private fun reindeersResults(reindeers: List<Reindeer>, time: Int): Int? {
val path = HashMap<Reindeer, Int>()
val score = HashMap<Reindeer, Int>()
for (reindeer in reindeers) {
path[reindeer] = 0
score[reindeer] = 0
}
for (t in 0 until time) {
reindeers
.filterNot { isResting(it, t) }
.forEach { path.computeIfPresent(it) { _, value -> value + it.speed } }
val leaders = path.entries.filter { it.value == path.values.max() }
for (leader in leaders) {
score.computeIfPresent(leader.key) { _, value -> value + 1 }
}
}
return score.values.max()
}
private fun isResting(reindeer: Reindeer, time: Int): Boolean = (time % (reindeer.rest + reindeer.time) >= reindeer.time)
private fun getDistance(time: Int, reindeer: Reindeer): Int {
var t = 0
var dist = 0
var flies = true
var currentTime = 0
while (t != time) {
t++
currentTime++
if (!flies) {
flies = currentTime == reindeer.rest
if (flies) currentTime = 0
} else {
dist += reindeer.speed
flies = currentTime != reindeer.time
if (!flies) currentTime = 0
}
}
return dist
}
private fun parseReindeer(info: List<String>): Reindeer = Reindeer(info[0], info[3].toInt(), info[6].toInt(), info[13].toInt())
data class Reindeer(val name: String, val speed: Int, val time: Int, val rest: Int)