expeditaet
Version:
Advent of Code Solutions
126 lines (109 loc) • 3.68 kB
text/typescript
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { task } from '@alexaegis/advent-of-code-lib';
import packageJson from '../package.json';
/**
*
* 0: 1: 2: 3: 4:
* aaaa .... aaaa aaaa ....
* b c . c . c . c b c
* b c . c . c . c b c
* .... .... dddd dddd dddd
* e f . f e . . f . f
* e f . f e . . f . f
* gggg .... gggg gggg ....
*
* 5: 6: 7: 8: 9:
* aaaa aaaa aaaa aaaa aaaa
* b . b . . c b c b c
* b . b . . c b c b c
* dddd dddd .... dddd dddd
* . f e f . f e f . f
* . f e f . f e f . f
* gggg gggg .... gggg gggg
*/
const getNumberFromCode = (
code: string,
segmentMap: Record<'a' | 'b' | 'c' | 'd' | 'e', string>,
): number => {
if (code.includes(segmentMap.a)) {
if (code.includes(segmentMap.b)) {
if (code.includes(segmentMap.c)) {
if (code.includes(segmentMap.d)) {
return code.includes(segmentMap.e) ? 8 : 9;
} else {
return 0;
}
} else {
return code.includes(segmentMap.e) ? 6 : 5;
}
} else {
if (code.includes(segmentMap.d)) {
return code.includes(segmentMap.e) ? 2 : 3;
} else {
return 7;
}
}
} else {
return code.includes(segmentMap.b) ? 4 : 1;
}
};
/**
* Characterset from A - B
*/
const getOnlyInFirst = (a: string, b: string): string => {
const aLetters = [...a];
const bLetters = new Set(b);
const result = aLetters.filter((aLetter) => !bLetters.has(aLetter));
return result.join('');
};
/**
* Character Intersection
*/
const getIntersecion = (a: string, b: string): string => {
const aLetters = [...a];
const bLetters = [...b];
const result = aLetters.filter((aLetter) => bLetters.find((bLetter) => aLetter === bLetter));
return result.join('');
};
/**
*
* @param codes of the 10 unique numbers!
* @returns mapping to the default segment locations
*/
const generateSegmentMap = (codes: string[]): Record<string, string> => {
const oneCF = codes.find((code) => code.length === 2);
const sevenACF = codes.find((code) => code.length === 3);
const fourBCDF = codes.find((code) => code.length === 4);
const twoThreeFiveABCDEFG = codes.filter((code) => code.length === 5);
const zeroSixNineABCDEFG = codes.filter((code) => code.length === 6);
const a = getOnlyInFirst(sevenACF!, oneCF!);
const bd = getOnlyInFirst(fourBCDF!, sevenACF!);
const [, /*_sixNineABCDEFG*/ [zeroABCEFG]] = zeroSixNineABCDEFG.partition((code) =>
[...bd].every((letter) => code.includes(letter)),
);
const d = getOnlyInFirst(fourBCDF!, zeroABCEFG!);
const b = getOnlyInFirst(bd, d);
const [[fiveABDFG], twoThreeACDEFG] = twoThreeFiveABCDEFG.partition((code) => code.includes(b));
const fg = getOnlyInFirst(fiveABDFG!, `${a}${b}${d}`);
const f = getIntersecion(fg, oneCF!);
const g = getOnlyInFirst(fg, f);
const c = getOnlyInFirst(oneCF!, f);
const [, /*[_threeACDFG]*/ [twoACDEG]] = twoThreeACDEFG.partition((code) => code.includes(f));
const e = getOnlyInFirst(twoACDEG!, `${a}${c}${d}${g}`);
return { a, b, c, d, e, f, g };
};
export const p2 = (input: string): number =>
input
.lines()
.map((line) => {
const [uniqueSignalPatterns, output] = line
.split(/ \| /)
.map((codes) => codes.split(/ /g));
const segmentMap = generateSegmentMap(uniqueSignalPatterns!);
return output!
.map((digit) => getNumberFromCode(digit, segmentMap).toString())
.join('')
.toInt();
})
.sum();
await task(p2, packageJson.aoc); // 1097568 ~0.95ms