day03.ts 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import { filter, isOutOfBound, map, mapWithIndex, reduce } from "fp-ts/lib/Array";
  2. import { pipe } from "fp-ts/lib/function";
  3. import { startsWith } from "fp-ts/lib/string";
  4. import { diagnostics } from "./input";
  5. import { diagnostics as testDiagnostics } from "./input.test";
  6. type Stat = { ones: number, zeros: number };
  7. const bitStats = (as: string[]): Stat[] => pipe(
  8. as,
  9. reduce(
  10. [] as Stat[],
  11. (acc, bits) => pipe(
  12. [...bits],
  13. mapWithIndex((i, b) => ({
  14. ones: b === "1" ? (acc[i]?.ones ?? 0) + 1 : (acc[i]?.ones ?? 0),
  15. zeros: b=== "0" ? (acc[i]?.zeros ?? 0) + 1 : (acc[i]?.zeros ?? 0)
  16. }))
  17. )
  18. )
  19. );
  20. const mostCommonBits = (as: Stat[]) => pipe(
  21. as,
  22. map(({ ones, zeros }) => ones < zeros ? "0" : "1")
  23. );
  24. const leastCommonBits = (as: Stat[]) => pipe(
  25. as,
  26. map(({ ones, zeros }) => ones < zeros ? "1" : "0")
  27. );
  28. const diagBitStats = pipe(
  29. diagnostics,
  30. bitStats
  31. );
  32. const gamma = pipe(diagBitStats, mostCommonBits).join("");
  33. const epsilon = pipe(diagBitStats, leastCommonBits).join("");
  34. console.log("gamma rate is ", gamma);
  35. console.log("epsilon rate is", epsilon);
  36. console.log("power consumption is", parseInt(gamma, 2) * parseInt(epsilon, 2));
  37. const calculator = (evaluate: typeof mostCommonBits) => (diagNumbers: string[]) => {
  38. const iterator = (as: string[], currFilter: string): string => {
  39. const filteredDiagNumbers = pipe(as, filter(startsWith(currFilter)));
  40. if (isOutOfBound(1, filteredDiagNumbers)) {
  41. return filteredDiagNumbers[0];
  42. }
  43. const newFilterChar = pipe(filteredDiagNumbers, bitStats, evaluate)[currFilter.length];
  44. return iterator(filteredDiagNumbers, currFilter + newFilterChar);
  45. }
  46. return iterator(diagNumbers, "");
  47. };
  48. const oxygenRatingCalculator = calculator(mostCommonBits);
  49. const co2RatingCalculator = calculator(leastCommonBits);
  50. const oxygenRating = pipe(diagnostics, oxygenRatingCalculator);
  51. const co2Rating = pipe(diagnostics, co2RatingCalculator);
  52. console.log("oxygen generator rating is", oxygenRating);
  53. console.log("CO2 scrubber rating is", co2Rating);
  54. console.log("life support rating is", parseInt(oxygenRating, 2) * parseInt(co2Rating, 2));