-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay7.kt
29 lines (22 loc) · 1.19 KB
/
Day7.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
package aoc2021.day07
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics
import kotlin.math.abs
import kotlin.math.round
fun getMinimumFuel(crabList: List<Int>, isPart2: Boolean = false): Int {
val stats = DescriptiveStatistics()
crabList.forEach { stats.addValue(it.toDouble()) }
val median = stats.getPercentile(50.0).toInt()
val mean = round(stats.mean).toInt()
// For Part 1, the minimum fuel is consumed moving close to the median position
// For Part 2, it's the mean. Additionally, the fuel used is found via the Gauss formula
val position = if (isPart2) mean else median
fun totalFuel(posDifference: Int): Int = if (isPart2) getSumOfFirstNNums(posDifference) else posDifference
val deltaToFuel = mutableMapOf<Int, Int>()
for (delta : Int in position - 5 .. position + 5) {
deltaToFuel[delta] = crabList.sumBy { totalFuel(abs(it - delta)) }
}
return deltaToFuel.minOf { it.value }
}
// In part 2, the total fuel to move from A to B is the Gauss formula applied to the steps, abs(B - A)
// E.g. to move from 1 to 5, that is 4 steps, fuel consumed is Gauss(5 - 1) = 10 units
fun getSumOfFirstNNums(n: Int): Int = n * (n + 1) / 2