Skip to content

Commit 13ebaf1

Browse files
committed
Solution 2015-17 (No Such Thing as Too Much)
1 parent 345c3b9 commit 13ebaf1

File tree

4 files changed

+85
-0
lines changed

4 files changed

+85
-0
lines changed

src/main/kotlin/de/ronny_h/aoc/extensions/Combinations.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package de.ronny_h.aoc.extensions
22

3+
import java.lang.Math.pow
4+
35

46
/**
57
* @return All pairwise combinations of list elements without the reflexive ones.
@@ -41,6 +43,23 @@ fun <E> permutationsOf(list: List<E>): Sequence<List<E>> = sequence {
4143
}
4244
}
4345

46+
fun <E> allSublistsOf(list: List<E>): Sequence<List<E>> = sequence {
47+
// count a binary number with list.size digits from 0...0 to 1...1
48+
var number = 0
49+
while (number < pow(2.0, list.size.toDouble())) {
50+
val sublist = ArrayList<E>(list.size)
51+
val binary = number.toString(2).reversed()
52+
// take the list elements at indices of the 1 bits
53+
binary.forEachIndexed { i, bit ->
54+
if (bit == '1') {
55+
sublist.add(list[i])
56+
}
57+
}
58+
yield(sublist)
59+
number++
60+
}
61+
}
62+
4463
/**
4564
* @return A sequence of `List<Int>` where each list is of length [n] and its elements count from `0` to [sum] in such a way
4665
* that `sum(list[0], list[1], ... list[n-1]) == [sum]`.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package de.ronny_h.aoc.year2015.day17
2+
3+
import de.ronny_h.aoc.AdventOfCode
4+
import de.ronny_h.aoc.extensions.allSublistsOf
5+
6+
fun main() = NoSuchThingAsTooMuch().run(654, 0)
7+
8+
class NoSuchThingAsTooMuch : AdventOfCode<Int>(2015, 17) {
9+
override fun part1(input: List<String>): Int =
10+
differentCombinationsToStore(input.map(String::toInt), 150)
11+
12+
override fun part2(input: List<String>): Int =
13+
differentWaysToStoreWithMinimalNumberOfContainers(input.map(String::toInt), 150)
14+
}
15+
16+
fun differentCombinationsToStore(containers: List<Int>, capacity: Int): Int =
17+
allSublistsOf(containers).count { it.sum() == capacity }
18+
19+
fun differentWaysToStoreWithMinimalNumberOfContainers(containers: List<Int>, capacity: Int): Int {
20+
var minimalNumberOfContainers = containers.size
21+
var count = 0
22+
allSublistsOf(containers).forEach {
23+
if (it.sum() == capacity) {
24+
if (it.size < minimalNumberOfContainers) {
25+
minimalNumberOfContainers = it.size
26+
count = 1
27+
} else if (it.size == minimalNumberOfContainers) {
28+
count++
29+
}
30+
}
31+
}
32+
return count
33+
}

src/test/kotlin/de/ronny_h/aoc/extensions/CombinationsTest.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,22 @@ class CombinationsTest : StringSpec({
8383
}
8484
}
8585

86+
"allSublistsOf for lists with up to three elements" {
87+
forAll(
88+
row(emptyList(), listOf(emptyList())),
89+
row(listOf(1), listOf(emptyList(), listOf(1))),
90+
row(listOf(1, 2), listOf(emptyList(), listOf(1), listOf(2), listOf(1, 2))),
91+
row(
92+
listOf(1, 2, 3), listOf(
93+
emptyList(), listOf(1), listOf(2), listOf(1, 2),
94+
listOf(3), listOf(1, 3), listOf(2, 3), listOf(1, 2, 3)
95+
)
96+
),
97+
) { list, expected ->
98+
allSublistsOf(list).toList() shouldBe expected
99+
}
100+
}
101+
86102
"sequenceNumbersOfEqualSum(n, sum) yields all lists of 'n' elements with a sum of 'sum'" {
87103
forAll(
88104
row(1, 100, listOf(listOf(100))),
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package de.ronny_h.aoc.year2015.day17
2+
3+
import io.kotest.core.spec.style.StringSpec
4+
import io.kotest.matchers.shouldBe
5+
6+
class NoSuchThingAsTooMuchTest : StringSpec({
7+
8+
val input = listOf(20, 15, 10, 5, 5)
9+
10+
"part 1: number of combinations to store 25 litres of eggnog" {
11+
differentCombinationsToStore(input, 25) shouldBe 4
12+
}
13+
14+
"part 2: number of combinations to store 25 litres of eggnog with minimal number of containers" {
15+
differentWaysToStoreWithMinimalNumberOfContainers(input, 25) shouldBe 3
16+
}
17+
})

0 commit comments

Comments
 (0)