|
|
@@ -0,0 +1,70 @@
|
|
|
+import { filter, isOutOfBound, map, mapWithIndex, reduce } from "fp-ts/lib/Array";
|
|
|
+import { pipe } from "fp-ts/lib/function";
|
|
|
+import { startsWith } from "fp-ts/lib/string";
|
|
|
+
|
|
|
+import { diagnostics } from "./input";
|
|
|
+import { diagnostics as testDiagnostics } from "./input.test";
|
|
|
+
|
|
|
+type Stat = { ones: number, zeros: number };
|
|
|
+
|
|
|
+const bitStats = (as: string[]): Stat[] => pipe(
|
|
|
+ as,
|
|
|
+ reduce(
|
|
|
+ [] as Stat[],
|
|
|
+ (acc, bits) => pipe(
|
|
|
+ [...bits],
|
|
|
+ mapWithIndex((i, b) => ({
|
|
|
+ ones: b === "1" ? (acc[i]?.ones ?? 0) + 1 : (acc[i]?.ones ?? 0),
|
|
|
+ zeros: b=== "0" ? (acc[i]?.zeros ?? 0) + 1 : (acc[i]?.zeros ?? 0)
|
|
|
+ }))
|
|
|
+ )
|
|
|
+ )
|
|
|
+);
|
|
|
+const mostCommonBits = (as: Stat[]) => pipe(
|
|
|
+ as,
|
|
|
+ map(({ ones, zeros }) => ones < zeros ? "0" : "1")
|
|
|
+);
|
|
|
+const leastCommonBits = (as: Stat[]) => pipe(
|
|
|
+ as,
|
|
|
+ map(({ ones, zeros }) => ones < zeros ? "1" : "0")
|
|
|
+);
|
|
|
+
|
|
|
+
|
|
|
+const diagBitStats = pipe(
|
|
|
+ diagnostics,
|
|
|
+ bitStats
|
|
|
+);
|
|
|
+const gamma = pipe(diagBitStats, mostCommonBits).join("");
|
|
|
+const epsilon = pipe(diagBitStats, leastCommonBits).join("");
|
|
|
+
|
|
|
+
|
|
|
+console.log("gamma rate is ", gamma);
|
|
|
+console.log("epsilon rate is", epsilon);
|
|
|
+console.log("power consumption is", parseInt(gamma, 2) * parseInt(epsilon, 2));
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+const calculator = (evaluate: typeof mostCommonBits) => (diagNumbers: string[]) => {
|
|
|
+ const iterator = (as: string[], currFilter: string): string => {
|
|
|
+ const filteredDiagNumbers = pipe(as, filter(startsWith(currFilter)));
|
|
|
+ if (isOutOfBound(1, filteredDiagNumbers)) {
|
|
|
+ return filteredDiagNumbers[0];
|
|
|
+ }
|
|
|
+ const newFilterChar = pipe(filteredDiagNumbers, bitStats, evaluate)[currFilter.length];
|
|
|
+ return iterator(filteredDiagNumbers, currFilter + newFilterChar);
|
|
|
+ }
|
|
|
+ return iterator(diagNumbers, "");
|
|
|
+};
|
|
|
+const oxygenRatingCalculator = calculator(mostCommonBits);
|
|
|
+const co2RatingCalculator = calculator(leastCommonBits);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+const oxygenRating = pipe(diagnostics, oxygenRatingCalculator);
|
|
|
+const co2Rating = pipe(diagnostics, co2RatingCalculator);
|
|
|
+
|
|
|
+console.log("oxygen generator rating is", oxygenRating);
|
|
|
+console.log("CO2 scrubber rating is", co2Rating);
|
|
|
+console.log("life support rating is", parseInt(oxygenRating, 2) * parseInt(co2Rating, 2));
|