Skip to content

Instantly share code, notes, and snippets.

@paszkowskiDamian
Last active September 23, 2021 16:45
Show Gist options
  • Save paszkowskiDamian/f60e57caa142561eae7d1f94458b8e10 to your computer and use it in GitHub Desktop.
Save paszkowskiDamian/f60e57caa142561eae7d1f94458b8e10 to your computer and use it in GitHub Desktop.
Brace balancing
const OPEN_BRACES = ['[', '{', '('] as const;
type OpenBrace = typeof OPEN_BRACES[number]
const CLOSED_BRACES = [']', '}', ')'] as const;
type ClosedBrace = typeof CLOSED_BRACES[number];
type AnyBrace = OpenBrace | ClosedBrace;
function isBraceOpen(brace: AnyBrace): brace is OpenBrace {
return OPEN_BRACES.includes(brace);
}
function isAnyBrace(brace: unknown): brace is AnyBrace {
return [...OPEN_BRACES, ...CLOSED_BRACES].includes(brace);
}
const MATCHING_BRACES: Record<OpenBrace, ClosedBrace> = {
"{": "}",
"[": "]",
"(": ")",
}
function areBracesBalanced(brances: AnyBrace[]) {
const stack: OpenBrace[] = [];
for (let brace of brances) {
if (isBraceOpen(brace)) {
stack.push(brace);
} else {
const lastBrace = stack.pop();
const expectedBrace = lastBrace && MATCHING_BRACES[lastBrace];
if (expectedBrace !== brace) {
return false;
}
}
}
if (stack.length === 0) {
return true;
}
return false
}
function areBracesBalancedRec(braces: AnyBrace[], stack: OpenBrace[] = []): boolean {
const [head, ...tail] = braces;
if (isBraceOpen(head)) {
return areBracesBalancedRec(tail, [head, ...stack]);
}
const [previousBrace, ...stackRest] = stack;
if (MATCHING_BRACES[previousBrace] !== head) {
return false;
}
if (tail.length === 0) {
return true;
}
return areBracesBalancedRec(tail, stackRest);;
}
const test = '[]{[()]}{}'.split('')
if (test.every(isAnyBrace)) {
console.log(areBracesBalancedRec(test))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment