96 lines
2 KiB
TypeScript
96 lines
2 KiB
TypeScript
|
enum LogLevel {
|
||
|
Answer,
|
||
|
Info,
|
||
|
Debug,
|
||
|
}
|
||
|
const LOG_LEVEL = LogLevel.Debug;
|
||
|
|
||
|
const print = (level: keyof typeof LogLevel, msg: string) => {
|
||
|
if (LogLevel[level] <= LOG_LEVEL) {
|
||
|
console.log(level+': '+msg);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const file = Bun.file("input.txt");
|
||
|
|
||
|
const input = await file.text();
|
||
|
|
||
|
function* findGears (schematic: string[]) {
|
||
|
const matcher = /\*/g;
|
||
|
|
||
|
for (const i in schematic) {
|
||
|
const line = schematic[i];
|
||
|
for (let res = matcher.exec(line); res !== null; res = matcher.exec(line)) {
|
||
|
const index = matcher.lastIndex - 1;
|
||
|
const end = matcher.lastIndex - 1;
|
||
|
print('Debug',`[${Number(i)+1},${index+1}]`);
|
||
|
yield {
|
||
|
line: Number(i),
|
||
|
index,
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
interface Match {
|
||
|
line: number,
|
||
|
index: number,
|
||
|
}
|
||
|
|
||
|
function neighbours (schematic: string[], match: Match): number[] {
|
||
|
const lastCol = schematic[0].length - 1;
|
||
|
const lastRow = schematic.length - 1;
|
||
|
|
||
|
function inbounds(x,y) {
|
||
|
return x >= 0 && y >= 0 && x <= lastCol && y <= lastRow;
|
||
|
}
|
||
|
|
||
|
const matches = [];
|
||
|
|
||
|
for (let y of [match.line-1, match.line, match.line+1]) {
|
||
|
let left = match.index-1;
|
||
|
while (inbounds(left,y) && /[0-9]/.test(schematic[y][left])) {
|
||
|
left--;
|
||
|
};
|
||
|
left = Math.max(left, 0);
|
||
|
let right = match.index+1;
|
||
|
while (inbounds(right,y) && /[0-9]/.test(schematic[y][right])) {
|
||
|
right++;
|
||
|
};
|
||
|
right = Math.min(right, lastCol+1);
|
||
|
|
||
|
const substr = schematic[y].slice(left,right);
|
||
|
const matcher = /[0-9]+/g;
|
||
|
for (let res = matcher.exec(substr); res !== null; res = matcher.exec(substr)) {
|
||
|
matches.push(...res)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
print('Debug', `neighbours: ${matches}`);
|
||
|
|
||
|
return matches.map(Number);
|
||
|
|
||
|
}
|
||
|
|
||
|
function main(): void {
|
||
|
const lines = input.trim().split("\n");
|
||
|
for (const line of lines) {
|
||
|
print('Info', line);
|
||
|
}
|
||
|
let total = 0;
|
||
|
for (const match of findGears(lines)) {
|
||
|
const nums = neighbours(lines,match)
|
||
|
if (nums.length === 2) {
|
||
|
const ratio = nums[0] * nums[1];
|
||
|
print('Debug', `adding ${ratio}`);
|
||
|
total += ratio;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
print('Answer', total);
|
||
|
}
|
||
|
|
||
|
main();
|
||
|
|
||
|
// too low: 83445843
|