Last active
December 8, 2021 21:16
-
-
Save ablamunits/cae4d81d37926a652635ccf085b904e6 to your computer and use it in GitHub Desktop.
AoC 2021 Day 8 Pt 2.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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