Files
advent-of-code-2022/2023/03/solution.ts
2023-12-07 21:43:51 +01:00

99 lines
2.5 KiB
TypeScript

const sample = await Deno.readTextFile("sample.txt");
const input = await Deno.readTextFile("input.txt");
interface Result<T> {
value: T;
line: number;
length: number;
index: number;
}
const isSymbol = (char: string): boolean =>
char !== undefined && isNaN(parseFloat(char)) && char !== ".";
const isGear = (char: string): boolean => char === "*";
const hasSurrounding = (
dataMap: string[],
{ line, index, length }: Result<number>,
predicate: (char: string) => boolean,
): { row: number; column: number }[] => {
const result: { row: number; column: number }[] = [];
for (let row = line - 1; row <= line + 1; row += 1) {
for (let column = index - 1; column < index + length + 1; column += 1) {
if (predicate(dataMap[row]?.[column])) result.push({ row, column });
}
}
return result;
};
const solvePart1 = (data: string): number => {
const dataMap = data
.split("\n")
.filter(Boolean);
return dataMap.map((line, index) =>
Array.from(
line.matchAll(/\d+/g),
(x): Result<number> => ({
value: parseFloat(x[0]),
line: index,
length: x[0].length,
index: x.index ?? -1,
}),
)
).flat()
.reduce(
(sum, result) =>
hasSurrounding(dataMap, result, isSymbol).length
? sum + result.value
: sum,
0,
);
};
console.log("Sample:", solvePart1(sample)); // 4361
console.log("Input", solvePart1(input)); // 550934
const solvePart2 = (data: string): number => {
const dataMap = data
.split("\n")
.filter(Boolean);
const numbersPerGear = dataMap.map((line, index) =>
Array.from(
line.matchAll(/\d+/g),
(x): Result<number> => ({
value: parseFloat(x[0]),
line: index,
length: x[0].length,
index: x.index ?? -1,
}),
)
).flat()
.map(
(result) => ({
...result,
gears: hasSurrounding(dataMap, result, isGear),
}),
).reduce((group, result): Record<string, number[]> => {
result.gears.forEach((gear) => {
group[`${gear.row}:${gear.column}`] = [
...(group[`${gear.row}:${gear.column}`] || []),
result.value,
];
});
return group;
}, {} as Record<string, number[]>);
return Object.values(numbersPerGear).reduce(
(sum, result) =>
result.length > 1 ? sum + result.reduce((s, v) => s * v) : sum,
0,
);
};
console.log("Sample2:", solvePart2(sample)); // 467835
console.log("Input", solvePart2(input)); // 81997870