1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// #folder:aoc2023
// @aoc2023
// @title Day 3 solutions
import getAocData from "https://esm.town/v/nbbaier/getAocData";
const data = await (await getAocData(3)).text();
const input = data.split("\n");
const symbolRegex: RegExp = new RegExp(
Array.from(new Set(data.split("\n").map(line => line.split("")).flat())).filter(char => !/[.\d]/.test(char)).map(
escapeRegex,
).join(
"|",
),
"g",
);
const numberRegex: RegExp = /\d+/g;
interface NumMetadata {
line: number;
idx: number;
number: string;
length: number;
adjacentPoints?: number[][];
}
interface SymbolMetadata {
point: number[];
symbol: string;
}
function getAdjacentCoordinates(point: number[]) {
const xPoint = point[0];
const yPoint = point[1];
const offsets = [-1, 0, 1];
const adjacentCoordinates = [];
for (const x of offsets) {
for (const y of offsets) {
if (x !== 0 || y !== 0) {
if (xPoint + x >= 0 && yPoint + y >= 0 && xPoint + x < input[yPoint].length && yPoint < input.length) {
adjacentCoordinates.push([xPoint + x, yPoint + y]);
}
}
}
}
return adjacentCoordinates;
}
function escapeRegex(str: string): string {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function hasOverlap(arr1, arr2) {
return arr1.some(point => arr2.some(compare => compare[0] === point[0] && compare[1] === point[1]));
}
function containsCoord(arr: number[][], target: number[]) {
return arr.some(subArr => JSON.stringify(subArr) === JSON.stringify(target));
}
let numbers: NumMetadata[] = input.flatMap((line, i) => {
let matches = [...line.matchAll(numberRegex)];
return matches.map(match => {
let number: NumMetadata = {
line: i,
idx: match.index,
number: match[0],
length: match[0].length,
};
let adjacentPoints = [];
for (let j = number.idx; j < number.length + number.idx; j++) {
const point = [j, number.line];
adjacentPoints.push(...getAdjacentCoordinates(point));
}
number.adjacentPoints = Array.from(new Set(adjacentPoints));
return number;
});
});
const symbols: SymbolMetadata[] = input.flatMap((row, i) =>
[...row.matchAll(symbolRegex)].map((match) => ({
point: [match.index!, i],
symbol: match[0],
}))
);
const gears: { gear: SymbolMetadata; adjacentNumbers: NumMetadata[]; count: number }[] = symbols.filter(item =>
item.symbol === "*"
).map(
potentialGear => {
const yBase = potentialGear.point[1];
const maybeAdjNums = numbers.filter(number => {
return Math.abs(number.line - yBase) <= 1;
});
return { potentialGear, maybeAdjNums };
},
).map(g => {
let count = 0;
let adjacentNumbers: NumMetadata[] = [];
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
February 21, 2024