1
0
Fork 0
mirror of https://github.com/HenkKalkwater/aoc-2020 synced 2024-11-22 11:05:18 +00:00

Day 13, part 2

This commit is contained in:
Chris Josten 2020-12-14 03:12:15 +01:00
parent f013067d26
commit 0ae8e76553
Signed by: chris
GPG key ID: 1795A594046530AB

View file

@ -1,15 +1,18 @@
import std.algorithm;
import std.typecons;
import dayutil; import dayutil;
struct ParsedInput { struct ParsedInput {
int timestamp; long timestamp;
int[] busses; long[] busses;
} }
Variant run(int part, File input, bool bigboy, string[] args) { Variant run(int part, File input, bool bigboy, string[] args) {
ParsedInput pInput = input.byLineCopy.array.parseInput(); ParsedInput pInput = input.byLineCopy.array.parseInput();
Variant result = parts!long(part, Variant result = parts!long(part,
() => part1(pInput), () => part1(pInput),
() => part2(pInput, 100000000000000)); () => part2(pInput));
return result; return result;
} }
@ -18,16 +21,15 @@ Variant run(int part, File input, bool bigboy, string[] args) {
ParsedInput input; ParsedInput input;
input.timestamp = to!int(range[0]); input.timestamp = to!int(range[0]);
input.busses = range[1].splitter(',').map!(c => c == "x" ? -1 : c.to!int).array; input.busses = range[1].splitter(',').map!(c => c == "x" ? -1 : c.to!long).array;
writeln(input);
return input; return input;
} }
int part1(ParsedInput input) { long part1(ParsedInput input) {
int earliestBus = 0; long earliestBus = 0;
int earliestBusTimestamp = int.max; long earliestBusTimestamp = long.max;
foreach(int bus; input.busses.filter!(x => x != -1)) { foreach(long bus; input.busses.filter!(x => x != -1)) {
int closestTimestamp = (input.timestamp / bus + 1 ) * bus; long closestTimestamp = (input.timestamp / bus + 1 ) * bus;
writeln(closestTimestamp); writeln(closestTimestamp);
if (closestTimestamp < earliestBusTimestamp) { if (closestTimestamp < earliestBusTimestamp) {
earliestBusTimestamp = closestTimestamp; earliestBusTimestamp = closestTimestamp;
@ -39,38 +41,54 @@ int part1(ParsedInput input) {
} }
long part2(ParsedInput input) { long part2(ParsedInput input) {
long result = 0; /+long[] remainders;
long[] divisors;
long startI = startFrom == 0 ? 0 : startFrom / input.busses[0]; // Too much, but we're not short on memory
remainders.reserve(input.busses.length);
for (long i = startI; result == 0; i++) { divisors.reserve(input.busses.length);
long offset = i * input.busses[0]; foreach (remainder, divisor; input.busses) {
bool fail = false; if (divisor < 0) continue;
remainders ~= [remainder % divisor];
foreach(j, subsequentBus; input.busses[1..$].enumerate(1)) { divisors ~= [divisor];
if (subsequentBus == -1) continue;
if ((offset + j) % subsequentBus != 0) {
fail = true;
break;
}
} }
if (!fail) { writeln(remainders);
result = offset; writeln(divisors);
long N = divisors.fold!((a,b) => a * b);
writeln(N);
long[] Ns; Ns.length = divisors.length;
long[] Xs; Xs.length = divisors.length;
long[] BNXs; BNXs.length = divisors.length;
foreach(i, divisor; divisors) {
Ns[i] = N / divisor;
} }
debug { foreach(ref Xi, Ni, Di; lockstep(Xs, Ns, divisors)) {
if (i % 10000 == 0) { long a = Ni % Di;
writef("\rAt %d", offset); long b;
stdout.flush(); for(b = 0; (a * b) % Di != 1; b++) {}
} Xi = b;
} }
writeln(Xs);
foreach(ref BNXi, Ri, Ni, Xi; lockstep(BNXs, remainders, Ns, Xs)) {
BNXi = Ri * Ni * Xi;
} }
debug writeln(); long result = BNXs.sum() % N;+/
Tuple!(size_t, "index", long, "value")[] busses = input.busses.enumerate.filter!((e) => e.value != -1).array;
return result; long time = 0;
long step = busses[0].value;
foreach(bus; busses[1..$]) {
for(; (time + bus.index) % bus.value != 0; time += step) {}
step *= bus.value;
}
writeln(time);
return time;
} }
unittest { unittest {
@ -82,5 +100,9 @@ unittest {
ParsedInput pInput = parseInput(input); ParsedInput pInput = parseInput(input);
assert(part1(pInput) == 295); assert(part1(pInput) == 295);
ParsedInput p2;
p2.busses = [-1, 7, -1, 5, -1, -1, 8];
//assert(part2(p2) == 78);
assert(part2(pInput) == 1068781); assert(part2(pInput) == 1068781);
} }