-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday24_partition.d
55 lines (43 loc) · 1.36 KB
/
day24_partition.d
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
/+ dub.sdl:
name "aoc24"
dependency "adventofcode" path="."
+/
pure @safe nothrow size_t minNeeded(const ulong[] weights, ulong target) {
import std.algorithm : sort;
ulong weightSoFar = 0;
size_t n = 0;
foreach (weight; weights.dup.sort!("a > b")) {
++n;
weightSoFar += weight;
if (weightSoFar >= target) {
return n;
}
}
return weights.length;
}
pure @safe immutable(ulong)[] partition(const ulong[] weights, uint numGroups) {
import std.algorithm : sum;
import combinations : combinations;
ulong total = weights.sum;
ulong eachGroup = total / numGroups;
for (size_t i = minNeeded(weights, eachGroup); i <= weights.length / numGroups; ++i) {
import std.algorithm : filter, minElement, reduce;
import std.array : array;
// Incorrect: Does not check for partitionability on the winning set.
auto winningCombos = array(weights.combinations(i).filter!(a => a.sum == eachGroup));
if (winningCombos.length != 0) {
return winningCombos.minElement!(c => c.reduce!("a * b"));
}
}
return weights.dup;
}
void main(string[] args) {
import std.algorithm : reduce;
import std.file : slurp;
import std.stdio : writeln;
const weights = slurp!(ulong)(args.length <= 1 ? "/dev/stdin" : args[1], "%d");
foreach (n; [3, 4]) {
const best = partition(weights, n);
writeln(best.reduce!("a * b"));
}
}