Skip to content

Instantly share code, notes, and snippets.

@ablamunits
Created December 10, 2021 10:54
Show Gist options
  • Save ablamunits/382a8df4308b3d69e84e883fb9c6c6f9 to your computer and use it in GitHub Desktop.
Save ablamunits/382a8df4308b3d69e84e883fb9c6c6f9 to your computer and use it in GitHub Desktop.
AoC 2021 Day 10
export const solveP1 = (input: string) => {
const rows = parseInput(input);
const scoreMap = {
')': 3,
']': 57,
'}': 1197,
'>': 25137
};
let score = 0;
rows.forEach((row) => {
const rowValidation = validateRow(row);
if (!rowValidation.isValid) {
score += scoreMap[rowValidation.lastChar];
}
});
return score;
};
export const solveP2 = (input: string) => {
const rows = parseInput(input);
const scoreMap = {
')': 1,
']': 2,
'}': 3,
'>': 4
};
const scores = [];
rows.forEach((row) => {
const stack = [];
const rowValidation = validateRow(row, stack);
if (rowValidation.isValid) {
// At this point, we are looking at an incomplete row.
// In this case the stack contains all opening brackets that need to be closed such
// that the item on the top is the next one that should be closed. The stack is reversed
// to start reducing with the top item first.
const score = stack.reverse().reduce((res, char) => (res * 5) + scoreMap[getPairedChar(char)], 0)
scores.push(score);
}
});
const midIdx = Math.floor(scores.length / 2);
return scores.sort((a, b) => a - b)[midIdx];
}
type RowValidationResult = {
isValid: boolean;
lastChar?: string;
}
const validateRow = (row: string[], stack: string[] = []): RowValidationResult => {
for (let i = 0; i < row.length; i++) {
const char = row[i];
if (isOpeningChar(char)) {
stack.push(char);
} else {
const lastOpeningChar = stack.pop();
if (!isValidPair(lastOpeningChar, char)) {
return { isValid: false, lastChar: char };
}
}
}
return { isValid: true }
}
/**
* ==================
* UTILITY FUNCTIONS
* ==================
*/
const parseInput = (input: string): string[][] => {
const rows = input.trim().split('\n');
return rows.map((row) => row.split(''));
}
const isValidPair = (opening: string, closing: string): boolean => {
return ['<>', '()', '[]', '{}'].includes(`${opening}${closing}`);
}
const isOpeningChar = (char: string): boolean => {
return ['(', '[', '{', '<'].includes(char);
}
const getPairedChar = (char: string): string => {
const pairingMap = {
'(': ')',
'[': ']',
'{': '}',
'<': '>',
'>': '<',
'}': '{',
']': '[',
')': '('
}
return pairingMap[char];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment