Here’s my solution to Day Three of Advent of Code.
Part 1
Today I reused a good bit of Part One on Part Two.
const testInput = `467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598..`;
const NUM_REGEX = /\d+/g;
let specialCharacters = /[^a-zA-Z0-9.]/g;
const parseInput = input => {
const numberPositions = [];
const specialCharPositions = [];
input.split("\n").forEach((line, row) => {
let match;
while ((match = NUM_REGEX.exec(line)) !== null) {
numberPositions.push({
x: match.index,
y: row,
number: parseInt(match[0]),
length: match[0].length,
});
}
NUM_REGEX.lastIndex = 0;
while ((match = specialCharacters.exec(line)) !== null) {
specialCharPositions.push({
x: match.index,
y: row,
char: match[0],
});
}
specialCharacters.lastIndex = 0;
});
return [numberPositions, specialCharPositions];
};
const findAdjacentNumbers = (specialCharPositions, numberPositions) => {
const numberList = [];
numberPositions.forEach(number => {
const numberEnd = number.x + number.length;
if (
specialCharPositions.some(
specialChar =>
specialChar.x >= number.x - 1 &&
specialChar.x <= numberEnd &&
specialChar.y >= number.y - 1 &&
specialChar.y <= number.y + 1
)
) {
numberList.push(number.number);
}
});
return numberList.reduce((a, b) => a + b, 0);
};
const [numberPositions, specialCharPositions] = parseInput(input);
console.log(findAdjacentNumbers(specialCharPositions, numberPositions)); // 4361
Part 2
// here I just reassigned the special characters variable
// so that I could reuse most of part one
specialCharacters = /[*]/g;
const calculateSumOfGearRatio = (gearPositions, numberPositions) => {
const numberList = gearPositions.map(gear => {
const adjacentNumbers = numberPositions
.filter(number => {
const numberEnd = number.x + number.length;
return (
gear.x >= number.x - 1 &&
gear.x <= numberEnd &&
gear.y >= number.y - 1 &&
gear.y <= number.y + 1
);
})
.map(number => number.number);
return adjacentNumbers.length === 2
? adjacentNumbers.reduce((a, b) => a * b, 1)
: 0;
});
return numberList.reduce((a, b) => a + b, 0);
};
const [numberPositionsPart2, gearPositions] = parseInput(testInput);
console.log(calculateSumOfGearRatio(gearPositions, numberPositionsPart2)); //467835
I really had to think about this one. For some reason I’ve always had a hard time mentally visualizing 2D array operations. Also, I wrote my RegEx for Part One poorly the first time and was missing a ton of entries. 🤦