2020-12-01 11:28:18 +00:00
|
|
|
import std.algorithm;
|
|
|
|
import std.array;
|
|
|
|
import std.conv;
|
|
|
|
import std.exception;
|
|
|
|
import std.format;
|
2020-12-01 14:42:11 +00:00
|
|
|
import std.functional;
|
2020-12-01 11:28:18 +00:00
|
|
|
import std.range;
|
|
|
|
import std.stdio;
|
2020-12-05 11:16:58 +00:00
|
|
|
import std.variant;
|
2020-12-01 11:28:18 +00:00
|
|
|
|
2020-12-01 14:42:11 +00:00
|
|
|
import dayutil;
|
|
|
|
|
2020-12-01 11:28:18 +00:00
|
|
|
immutable string progName = "aoc-2020";
|
|
|
|
|
2020-12-07 05:05:35 +00:00
|
|
|
Variant run(int part, File input, bool bigboy, string[] args) {
|
2020-12-01 11:28:18 +00:00
|
|
|
|
2020-12-01 14:42:11 +00:00
|
|
|
/* For each line on stdin, copy it, map it to an integer and sort it.
|
|
|
|
Sorting a range makes it a SortedRange and functions like contains(range, elem)
|
2020-12-02 16:53:43 +00:00
|
|
|
will make use of optimised implementations, in the case of contains(range, elem)
|
2020-12-01 14:42:11 +00:00
|
|
|
it will use a binary search instead of a linear search */
|
2020-12-05 11:16:58 +00:00
|
|
|
auto numbers = input.byLineCopy.map!(a => to!int(a)).array.sort;
|
2020-12-07 05:05:35 +00:00
|
|
|
int target = bigboy ? 99920044 : 2020;
|
2020-12-01 11:28:18 +00:00
|
|
|
|
2020-12-07 05:05:35 +00:00
|
|
|
Variant solution = parts!int(part,
|
|
|
|
() => part1(numbers, target),
|
|
|
|
() => part2(numbers, target));
|
2020-12-01 14:42:11 +00:00
|
|
|
enforce(solution >= 0, "No solutions found");
|
2020-12-05 11:16:58 +00:00
|
|
|
return solution;
|
2020-12-01 11:28:18 +00:00
|
|
|
}
|
|
|
|
|
2020-12-07 05:05:35 +00:00
|
|
|
int part1(SortedRange!(int[]) numbers, int target) {
|
2020-12-01 11:28:18 +00:00
|
|
|
int result = -1;
|
|
|
|
|
|
|
|
foreach (ref int a; numbers) {
|
2020-12-07 05:05:35 +00:00
|
|
|
int b = target - a;
|
2020-12-01 11:28:18 +00:00
|
|
|
if (numbers.contains(b)) {
|
|
|
|
result = b * a;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
unittest {
|
|
|
|
auto numbers = [1721, 979, 366, 299, 675, 1456].sort;
|
|
|
|
assert(part1(numbers) == 514579);
|
|
|
|
}
|
|
|
|
|
2020-12-07 05:05:35 +00:00
|
|
|
int part2(SortedRange!(int[]) numbers, int target) {
|
2020-12-01 11:28:18 +00:00
|
|
|
int result = -1;
|
|
|
|
foreach (ref int a; numbers) {
|
|
|
|
foreach (ref int b; numbers) {
|
2020-12-07 05:05:35 +00:00
|
|
|
int c = target - b - a;
|
2020-12-01 11:28:18 +00:00
|
|
|
if (numbers.contains(c)) {
|
|
|
|
result = c * b * a;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
exit:
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
unittest {
|
|
|
|
auto numbers = [1721, 979, 366, 299, 675, 1456].sort;
|
|
|
|
assert(part2(numbers) == 241861950);
|
|
|
|
}
|