1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- import { ExtractNumbers, LoadInput } from "../common.ts";
- const tests = [
- "Time: 7 15 30",
- "Distance: 9 40 200",
- ];
- const input = await LoadInput(6);
- const races = ParseRaces(input);
- races.forEach((race) => FindWinningTimes(race));
- // Get our output as a "checksum"
- // The checksum is the number of ways each race could be won multiplied by each other
- console.log("The race checksum is", races.reduce((accumulator, race) => accumulator *= race.WinningTimes.length, 1));
- /**
- * Parse the input to get a list of races
- *
- * @param {string[]} inputLines The two lines of input
- * @returns {Race[]} A list of race details
- */
- function ParseRaces(inputLines: string[]): Race[] {
- const races: Race[] = [];
- const times = ExtractNumbers(inputLines.shift() || "");
- const distances = ExtractNumbers(inputLines.shift() || "");
- do {
- races.push({
- Duration: times.shift() || -1,
- RecordDistance: distances.shift() || -1,
- WinningTimes: [],
- });
- } while (times.length);
- return races;
- }
- /**
- * Find all possible winning times for a given race
- *
- * @param {Race} race The race to find winning times for
- */
- function FindWinningTimes(race: Race) {
- // For our sake, flip the sign on the RecordDistance to create a floor for the parabola
- let [lowerBounds, upperBounds] = FindQuadraticRoots(-1, race.Duration, (race.RecordDistance * -1));
- // Exclusively bind the two bounds to integers
- // Add/subtract 0.01 to force integer roots to their next whole number
- lowerBounds = Math.ceil(lowerBounds + 0.01);
- upperBounds = Math.floor(upperBounds - 0.01);
- for(let i = lowerBounds; i <= upperBounds; i++) { race.WinningTimes.push(i); }
- }
- /**
- * Find the quadratic roots of a parabola
- *
- * @param a
- * @param b
- * @param c
- * @returns The quadratic roots of a parabola
- */
- function FindQuadraticRoots(a: number, b: number, c: number): number[] {
- if (a == 0) { return []; }
- // Solve for the discriminant -- sqrt(b^2 - 4ac)
- const discriminant = Math.sqrt(Math.pow(b, 2) - (4 * a * c));
-
- return [
- ((b * -1) + discriminant) / (2 * a),
- ((b * -1) - discriminant) / (2 * a),
- ];
- }
- /**
- * Information regarding a boat race
- */
- type Race = {
- /** The total duration of the race in milliseconds */
- Duration: number,
- /** The current record holder for boat distance */
- RecordDistance: number,
- /** A list of times the boat's button could be held that would beat the RecordDistance */
- WinningTimes: number[]
- };
|