Skip to content

Instantly share code, notes, and snippets.

@ablamunits
Last active December 8, 2021 21:16
Show Gist options
  • Save ablamunits/cae4d81d37926a652635ccf085b904e6 to your computer and use it in GitHub Desktop.
Save ablamunits/cae4d81d37926a652635ccf085b904e6 to your computer and use it in GitHub Desktop.
AoC 2021 Day 8 Pt 2.
enum Segment {
Top = 'top',
TopRight = 'top-right',
BottomRight = 'bottom-right',
Bottom = 'bottom',
BottomLeft = 'bottom-left',
TopLeft = 'top-left',
Middle = 'middle',
}
const digitToSegments = {
0: [Segment.Top, Segment.TopRight, Segment.BottomRight, Segment.Bottom, Segment.BottomLeft, Segment.TopLeft],
1: [Segment.TopRight, Segment.BottomRight],
2: [Segment.Top, Segment.TopRight, Segment.Middle, Segment.BottomLeft, Segment.Bottom],
3: [Segment.Top, Segment.TopRight, Segment.Middle, Segment.BottomRight, Segment.Bottom],
4: [Segment.TopLeft, Segment.TopRight, Segment.Middle, Segment.BottomRight],
5: [Segment.Top, Segment.TopLeft, Segment.Middle, Segment.BottomRight, Segment.Bottom],
6: [Segment.Top, Segment.TopLeft, Segment.Middle, Segment.Bottom, Segment.BottomRight, Segment.BottomLeft],
7: [Segment.Top, Segment.TopRight, Segment.BottomRight],
8: [Segment.Top, Segment.TopRight, Segment.Bottom, Segment.BottomRight, Segment.BottomLeft, Segment.TopLeft, Segment.Middle],
9: [Segment.Top, Segment.TopRight, Segment.Bottom, Segment.BottomRight, Segment.TopLeft, Segment.Middle]
}
const getDigitFromSegments = (segments: Segment[]): number => {
const d = Object.keys(digitToSegments).find((key) => digitToSegments[key].sort().join('') === segments.sort().join(''));
return Number(d);
}
const parseOutput = (output: string[], wireToSegment: Map<string, Segment>): number => {
return output.reduce((res, wires) => {
const segments = wires.split('').map(w => wireToSegment.get(w));
const digit = getDigitFromSegments(segments);
return Number(`${res}${digit}`);
}, 0);
}
export const solveP2 = (input: string): number => {
const entries = parseInput(input);
const updateSegmentMap = (map: Map<string, Segment>, digit: number, pattern: string, entry: Entry) => {
switch(digit) {
case 1: {
if (pattern.length !== 2) return;
const [w1, w2] = pattern.split('');
const w1Count = entry.patterns.filter(p => p.includes(w1)).length;
if (w1Count === 9) {
map.set(w1, Segment.BottomRight);
map.set(w2, Segment.TopRight);
} else {
map.set(w1, Segment.TopRight);
map.set(w2, Segment.BottomRight);
}
break;
}
case 7:
if (pattern.length !== 3) return;
const threeWires = pattern.split('');
const missingWire = threeWires.find(w => !map.has(w));
map.set(missingWire, Segment.Top);
break;
case 4:
if (pattern.length !== 4) return;
const [w1, w2] = pattern.split('').filter(w => !map.has(w));
const w1Count = entry.patterns.filter(p => p.includes(w1)).length;
if (w1Count === 7) {
map.set(w1, Segment.Middle);
map.set(w2, Segment.TopLeft);
} else {
map.set(w1, Segment.TopLeft);
map.set(w2, Segment.Middle);
}
break;
case 5:
if (pattern.length !== 5) return;
const fiveSegmentPatterns = entry.patterns.filter((pattern) => pattern.length === 5);
const bottomWire = pattern.split('').find((wire) => {
if (map.has(wire)) return false;
return fiveSegmentPatterns.every(pattern => pattern.includes(wire));
});
map.set(bottomWire, Segment.Bottom);
break;
}
}
const entryOutputs = entries.map((entry) => {
const wireToSegmentMap = new Map<string, Segment>();
// Find 1
const onePattern = entry.patterns.find((pattern) => pattern.length === 2);
updateSegmentMap(wireToSegmentMap, 1, onePattern, entry);
// Find 7
const sevenPattern = entry.patterns.find((pattern) => pattern.length === 3);
updateSegmentMap(wireToSegmentMap, 7, sevenPattern, entry);
// Find 4
const fourPattern = entry.patterns.find((pattern) => pattern.length === 4);
updateSegmentMap(wireToSegmentMap, 4, fourPattern, entry);
// Find 5
entry.patterns.filter(p => p.length === 5).forEach((fivePattern) => {
updateSegmentMap(wireToSegmentMap, 5, fivePattern, entry)
});
// Last one is bottom left.. find the missing wire
const missing = ['a', 'b', 'c', 'd', 'e', 'f', 'g'].find((w) => !wireToSegmentMap.has(w));
wireToSegmentMap.set(missing, Segment.BottomLeft);
// Finally parse the entry output
return parseOutput(entry.output, wireToSegmentMap);
});
return entryOutputs.reduce((a, b) => a + b, 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment