generated from Jadarma/advent-of-code-kotlin-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Y2015D24.kt
58 lines (48 loc) · 2.18 KB
/
Y2015D24.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
package aockt.y2015
import io.github.jadarma.aockt.core.Solution
object Y2015D24 : Solution {
/**
* Returns a sequence of all combinations of size [take] from the initial list.
* This is a refactor of a Rosetta Code snippet, available at [https://rosettacode.org/wiki/Combinations#Kotlin].
* TODO: Make Util.
*/
private fun List<Int>.combinations(take: Int): Sequence<List<Int>> = sequence {
val combination = IntArray(take) { first() }
val stack = ArrayDeque<Int>().apply { addFirst(0) }
while (stack.isNotEmpty()) {
var resIndex = stack.size - 1
var arrIndex = stack.removeFirst()
while (arrIndex < size) {
combination[resIndex++] = get(arrIndex++)
stack.addFirst(arrIndex)
if (resIndex == take) {
yield(combination.toList())
break
}
}
}
}
/**
* Returns the quantum entanglement for the best group of packages that can go in Santa's passenger compartiment,
* or `null` if there is no solution.
*
* **NOTE:** This isn't really the solution, since it only finds the ideal first group but doesn't check that the
* rest of the presents can be split in equal groups. However, it seems the input data for all advent participants
* the first ideal bucket is always part of a solution. Sadly, Santa only gets the value of the QE, not the actual
* split, and his sled would remain unbalanced.
*/
private fun minQuantumEntanglement(pool: List<Int>, buckets: Int): Long? {
if (buckets < 1) return null
val target = pool.sum() / buckets
for (bucketSize in 1..pool.size) {
return pool
.combinations(take = bucketSize)
.filter { it.sum() == target }
.minOfOrNull { it.fold(1L, Long::times) }
?: continue
}
return null
}
override fun partOne(input: String) = input.lines().map(String::toInt).let { minQuantumEntanglement(it, 3)!! }
override fun partTwo(input: String) = input.lines().map(String::toInt).let { minQuantumEntanglement(it, 4)!! }
}