aoc-2024/day_3/solve_2.ts

96 lines
1.7 KiB
TypeScript
Raw Permalink Normal View History

2024-12-05 13:55:07 +09:00
import { Lexer } from "./lexer.ts";
const txt = await Deno.readTextFile("input.txt");
const lexer = new Lexer(txt);
type Expr = {
type: "mul";
left: number;
right: number;
} | {
type: "do";
} | {
type: "don't";
}
function parseMulExpr(
lexer: Lexer,
): Expr | null {
if (!lexer.match("mul(")) {
return null;
}
const left = lexer.matchDigitN(1,3);
if (!left) {
return null;
}
if (!lexer.match(",")) {
return null;
}
const right = lexer.matchDigitN(1,3);
if (!right) {
return null;
}
if (!lexer.match(")")) {
return null;
}
return {
type: "mul",
left: parseInt(left),
right: parseInt(right),
};
}
function parseDoExpr(
lexer: Lexer,
): Expr | null {
if (!lexer.match("do()")) {
return null;
}
return {
type: "do",
};
}
function parseDontExpr(
lexer: Lexer,
): Expr | null {
if (!lexer.match("don't()")) {
return null;
}
return {
type: "don't",
};
}
function parseExpr(
lexer: Lexer,
): Expr | null {
return parseDoExpr(lexer) ?? parseDontExpr(lexer) ?? parseMulExpr(lexer);
}
const exprs: Expr[] = [];
while (lexer.pos < lexer.str.length) {
const expr = parseExpr(lexer);
if (expr) {
exprs.push(expr);
}
else {
lexer.next();
}
}
let sum = 0;
let enabled = true;
for (const expr of exprs) {
if (expr.type === "do") {
enabled = true;
}
else if (expr.type === "don't") {
enabled = false;
}
else if (enabled && expr.type === "mul") {
sum += expr.left * expr.right;
}
}
console.log(sum);