6_2.ts 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import { ExtractNumbers, LoadInput } from "../common.ts";
  2. const tests = [
  3. "Time: 7 15 30",
  4. "Distance: 9 40 200",
  5. ];
  6. const input = await LoadInput(6);
  7. const theRace = ParseRaces(input);
  8. FindWinningTimes(theRace);
  9. console.log("The amount of possible race wins is:", theRace.WinningTimesQuantity);
  10. /**
  11. * Parse the input to get a list of races
  12. *
  13. * @param {string[]} inputLines The two lines of input
  14. * @returns {Race[]} A list of race details
  15. */
  16. function ParseRaces(inputLines: string[]): Race {
  17. // The quote unquote times of the race
  18. const times = ExtractNumbers(inputLines.shift() || "");
  19. // The quote unquote distances of the race
  20. const distances = ExtractNumbers(inputLines.shift() || "");
  21. return {
  22. Duration: Number(times.join("")),
  23. RecordDistance: Number(distances.join("")),
  24. WinningTimesQuantity: -1,
  25. };
  26. }
  27. /**
  28. * Find all possible winning times for a given race
  29. *
  30. * @param {Race} race The race to find winning times for
  31. */
  32. function FindWinningTimes(race: Race) {
  33. // For our sake, flip the sign on the RecordDistance to create a floor for the parabola
  34. let [lowerBounds, upperBounds] = FindQuadraticRoots(-1, race.Duration, (race.RecordDistance * -1));
  35. // Exclusively bind the two bounds to integers
  36. // Add/subtract 0.01 to force integer roots to their next whole number
  37. lowerBounds = Math.ceil(lowerBounds + 0.01);
  38. upperBounds = Math.floor(upperBounds - 0.01);
  39. race.WinningTimesQuantity = upperBounds - lowerBounds + 1;
  40. }
  41. /**
  42. * Find the quadratic roots of a parabola
  43. *
  44. * @param a
  45. * @param b
  46. * @param c
  47. * @returns The quadratic roots of a parabola
  48. */
  49. function FindQuadraticRoots(a: number, b: number, c: number): number[] {
  50. if (a == 0) { return []; }
  51. // Solve for the discriminant -- sqrt(b^2 - 4ac)
  52. const discriminant = Math.sqrt(Math.pow(b, 2) - (4 * a * c));
  53. return [
  54. ((b * -1) + discriminant) / (2 * a),
  55. ((b * -1) - discriminant) / (2 * a),
  56. ];
  57. }
  58. /**
  59. * Information regarding a boat race
  60. */
  61. type Race = {
  62. /** The total duration of the race in milliseconds */
  63. Duration: number,
  64. /** The current record holder for boat distance */
  65. RecordDistance: number,
  66. /** The amount of ways you hold the button in order to beat the RecordDistance */
  67. WinningTimesQuantity: number
  68. };