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:
parent
f013067d26
commit
0ae8e76553
100
source/day13.d
100
source/day13.d
|
@ -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];
|
|
||||||
|
|
||||||
for (long i = startI; result == 0; i++) {
|
|
||||||
long offset = i * input.busses[0];
|
|
||||||
bool fail = false;
|
|
||||||
|
|
||||||
foreach(j, subsequentBus; input.busses[1..$].enumerate(1)) {
|
|
||||||
if (subsequentBus == -1) continue;
|
|
||||||
|
|
||||||
if ((offset + j) % subsequentBus != 0) {
|
|
||||||
fail = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fail) {
|
|
||||||
result = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug {
|
|
||||||
if (i % 10000 == 0) {
|
|
||||||
writef("\rAt %d", offset);
|
|
||||||
stdout.flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Too much, but we're not short on memory
|
||||||
|
remainders.reserve(input.busses.length);
|
||||||
|
divisors.reserve(input.busses.length);
|
||||||
|
foreach (remainder, divisor; input.busses) {
|
||||||
|
if (divisor < 0) continue;
|
||||||
|
remainders ~= [remainder % divisor];
|
||||||
|
divisors ~= [divisor];
|
||||||
}
|
}
|
||||||
debug writeln();
|
|
||||||
|
|
||||||
return result;
|
writeln(remainders);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(ref Xi, Ni, Di; lockstep(Xs, Ns, divisors)) {
|
||||||
|
long a = Ni % Di;
|
||||||
|
long b;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
long result = BNXs.sum() % N;+/
|
||||||
|
Tuple!(size_t, "index", long, "value")[] busses = input.busses.enumerate.filter!((e) => e.value != -1).array;
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue