Skip to content

Instantly share code, notes, and snippets.

@niedziek
Last active January 2, 2024 15:02
Show Gist options
  • Save niedziek/3ced2a1d3cdabab34ee748136b979cbb to your computer and use it in GitHub Desktop.
Save niedziek/3ced2a1d3cdabab34ee748136b979cbb to your computer and use it in GitHub Desktop.
AoC Day 3
import * as fs from "fs";
const lines: string[] = fs.readFileSync("input.txt", "utf-8").split("\n");
let numbersList = getNumbers();
let count = 0;
countValidNumbers(numbersList);
console.log(count);
function getNumbers() {
let numbersList: Number[] = [];
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const numberPattern = /\d+/g;
let match;
while ((match = numberPattern.exec(line)) !== null) {
const foundItem: Number = {
number: parseInt(match[0]),
start: match.index,
end: match.index + match[0].length,
line,
lineNumber: i,
};
numbersList.push(foundItem);
}
}
return numbersList;
}
function countValidNumbers(numbersList: Number[]) {
for (const number of numbersList) {
const currentLine = number.line;
let previousLine;
if (number.lineNumber === 0) {
previousLine = null;
} else {
previousLine = lines[number.lineNumber - 1];
}
let nextLine;
if (number.lineNumber === lines.length - 1) {
nextLine = null;
} else {
nextLine = lines[number.lineNumber + 1];
}
// check same line symbols
if (
(number.start > 0 && isSymbol(currentLine[number.start - 1])) ||
isSymbol(currentLine[number.end])
) {
count += number.number;
continue;
}
//check above and below line symbols
for (let i = number.start - 1; i <= number.end; i++) {
if (i >= currentLine.length || i < 0) {
continue;
}
if (
(previousLine !== null && isSymbol(previousLine[i])) ||
(nextLine !== null && isSymbol(nextLine[i]))
) {
count += number.number;
break;
}
}
}
}
function isSymbol(char: string) {
if (char.match(/\d/) || char === "." || char === "\r") {
return false;
}
return true;
}
type Number = {
number: number;
start: number;
end: number;
line: string;
lineNumber: number;
};
import * as fs from "fs";
let count = 0;
const lines: string[] = fs.readFileSync("input.txt", "utf-8").split("\n");
let numbersList = getNumbers();
let starsList = getStars();
countGears();
console.log(count);
function getNumbers(): NumberItem[] {
const numberPattern = /\d+/g;
return lines.flatMap((line, lineNumber) => {
let matches = Array.from(line.matchAll(numberPattern));
let numbersList: NumberItem[] = [];
if (!matches) {
return numbersList;
}
matches.forEach((match) => {
const foundItem: NumberItem = {
number: parseInt(match[0]),
start: match.index ?? 0,
end: (match.index ?? 0) + match[0].length - 1,
line,
lineNumber: lineNumber,
};
numbersList.push(foundItem);
});
return numbersList;
});
}
function getStars() {
let starsList: Star[] = [];
for (let i = 0; i < lines.length; i++) {
let line = lines[i];
for (let j = 0; j < line.length; j++) {
if (line[j] === "*") {
let star: Star = {
position: j,
line: line,
lineNumber: i,
};
starsList.push(star);
}
}
}
return starsList;
}
function countGears() {
for (const star of starsList) {
//get numbers that are below, above or on the same line
//if position of any of their digit aligns with any position we look for we add it to the list
let adjacentNumbers = numbersList.filter(
(number) =>
[star.lineNumber - 1, star.lineNumber, star.lineNumber + 1].includes(
number.lineNumber
) &&
createArray(number.start, number.end).some((value) =>
[star.position - 1, star.position, star.position + 1].includes(value)
)
);
if (adjacentNumbers.length === 2) {
count += adjacentNumbers[0].number * adjacentNumbers[1].number;
}
}
}
function createArray(start: number, end: number) {
const result: number[] = [];
for (let i = start; i <= end; i++) {
result.push(i);
}
return result;
}
type NumberItem = {
number: number;
start: number;
end: number;
line: string;
lineNumber: number;
};
type Star = {
position: number;
line: string;
lineNumber: number;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment