51 lines
1.4 KiB
D
51 lines
1.4 KiB
D
|
import std.stdio;
|
||
|
import std.array;
|
||
|
import std.algorithm;
|
||
|
import std.string;
|
||
|
import std.conv;
|
||
|
import std.math;
|
||
|
|
||
|
struct Race {
|
||
|
long time, dist;
|
||
|
}
|
||
|
|
||
|
Race[] parseRaces(string filename) {
|
||
|
string[] lines = File(filename).byLineCopy.array;
|
||
|
long[] times = lines[0].split(":")[1].strip.split.map!(to!long).array;
|
||
|
long[] distances = lines[1].split(":")[1].strip.split.map!(to!long).array;
|
||
|
Race[] result = new Race[](times.length);
|
||
|
foreach (size_t i, long time; times) {
|
||
|
result[i] = Race(time, distances[i]);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
Race parseKernedRace(string filename) {
|
||
|
string[] lines = File(filename).byLineCopy.array;
|
||
|
long time = lines[0].split(":")[1].strip.split.join.to!long;
|
||
|
long dist = lines[1].split(":")[1].strip.split.join.to!long;
|
||
|
return Race(time, dist);
|
||
|
}
|
||
|
|
||
|
long computeSolutions(in Race r) {
|
||
|
double D = r.time * r.time - 4 * r.dist;
|
||
|
double t1 = (-r.time + sqrt(D)) / -2;
|
||
|
double t2 = (-r.time - sqrt(D)) / -2;
|
||
|
long minWinningTime = cast(long) (ceil(t1) == t1 ? t1 + 1 : ceil(t1));
|
||
|
long maxWinningTime = cast(long) (floor(t2) == t2 ? t2 - 1 : floor(t2));
|
||
|
return maxWinningTime - minWinningTime + 1;
|
||
|
}
|
||
|
|
||
|
void part1() {
|
||
|
parseRaces("input.txt").map!computeSolutions.fold!((a, b) => a * b).writeln;
|
||
|
|
||
|
}
|
||
|
|
||
|
void part2() {
|
||
|
parseKernedRace("input.txt").computeSolutions.writeln;
|
||
|
}
|
||
|
|
||
|
void main() {
|
||
|
part1();
|
||
|
part2();
|
||
|
}
|