| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- import * as A from "fp-ts/Array";
- import * as S from "fp-ts/string";
- import * as RA from "fp-ts/ReadonlyArray";
- import * as N from "fp-ts/number";
- import { flow, pipe } from "fp-ts/lib/function";
- import { concatAll } from "fp-ts/lib/Monoid";
- import { fromCompare } from "fp-ts/Ord";
- import { signalPatterns as testSignalPatterns } from "./input.test";
- import { signalPatterns as inputSignalPatterns } from "./input";
- type SignalPatterns = {
- patterns: string[],
- digits: string[]
- };
- const parseSignalPatterns = (input: string) => pipe(
- input.split("\n"),
- A.map(lines => lines.split(" | ")),
- A.map(lineParts => pipe(lineParts, A.map(parts => parts.split(" ")))),
- A.map(([patterns, digits]) => ({ patterns, digits }))
- );
- const signalPatterns = parseSignalPatterns(
- // testSignalPatterns
- inputSignalPatterns
- );
- const easyDigitCount = pipe(
- signalPatterns,
- A.map(signalPattern => signalPattern.digits),
- A.flatten,
- A.reduce(0, (count, digit) => pipe([2, 4, 3, 7], A.some(n => n === digit.length)) ? count + 1 : count)
- );
- console.log(easyDigitCount);
- type PatternKey = { [pattern: string]: string };
- const deductKey = (patterns: string[]): PatternKey => {
- return pipe(
- patterns,
- A.map(p => pipe(p, S.split(""), RA.sort(S.Ord), concatAll(S.Monoid))),
- A.sort(fromCompare((a: string, b: string) => a.length < b.length ? -1 : a.length > b.length ? 1 : 0)),
- A.reduce({} as PatternKey, (key, pattern) => {
- const segmentsOf = (value: string) => pipe(
- pipe(Object.keys(key), A.filter(k => key[k] === value)),
- A.map(S.split("")),
- RA.flatten
- );
- const contains = (segments: readonly string[]) => (pattern: string) => pipe(
- segments,
- RA.reduce(true, (res, segment) => res && S.includes(segment)(pattern))
- )
- switch ((pipe(pattern, S.size))) {
- case 2:
- return { ...key, [pattern]: "1" };
- case 3:
- return { ...key, [pattern]: "7" };
- case 4:
- return { ...key, [pattern]: "4" };
- case 5:
- if (pipe(pattern, contains(segmentsOf("1")))) {
- return { ...key, [pattern]: "3" };
- }
- if (pipe(pattern, contains(pipe(segmentsOf("4"), RA.difference(S.Eq)(segmentsOf("1")))))) {
- return { ...key, [pattern]: "5"};
- }
- return { ...key, [pattern]: "2" };
- case 6:
- if (pipe(pattern, contains(segmentsOf("4")))) {
- return { ...key, [pattern]: "9" };
- }
- if (pipe(pattern, contains(segmentsOf("7")))) {
- return { ...key, [pattern]: "0" };
- }
- return { ...key, [pattern]: "6" };
- case 7:
- return { ...key, [pattern]: "8" };
- default:
- return key;
- }
- })
- );
- }
- const solveDigit = (key: PatternKey) => (digit: string): string => {
- return key[pipe(digit, S.split(""), RA.sort(S.Ord), concatAll(S.Monoid))] ?? "X";
- }
- const displayDigits = pipe(
- signalPatterns,
- A.map(sp => ({ key: deductKey(sp.patterns), digits: sp.digits })),
- A.map(({ key, digits }) => pipe(digits, A.map(flow(solveDigit(key))))),
- A.map(concatAll(S.Monoid)),
- A.map(parseInt)
- );
- console.log(pipe(displayDigits, concatAll(N.MonoidSum)));
|