feat(2024-02): Add day 2

This commit is contained in:
Josh Creek
2024-12-03 22:00:58 +00:00
parent a244a3e4bc
commit dcb57b569d
2 changed files with 1149 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+149
View File
@@ -0,0 +1,149 @@
const fs = require("fs");
const path = require("path");
describe("2024 Day 02", () => {
let realData;
beforeAll(() => {
const filePath = path.resolve(__dirname, "./Data/Day02.dat");
realData = fs.readFileSync(filePath, "utf-8").split("\n");
});
function areNumbersAllIncreasingOrDecreasing(numbers) {
if (numbers.length <= 1) {
// If there's only one number, it's either increasing or decreasing
return true;
}
let isIncreasing = true;
let isDecreasing = true;
for (let i = 1; i < numbers.length; i++) {
if (numbers[i] > numbers[i - 1]) {
isDecreasing = false;
} else if (numbers[i] < numbers[i - 1]) {
isIncreasing = false;
}
if (!isIncreasing && !isDecreasing) {
return false;
}
}
return true;
}
function areAdjacentNumbersWithinRange(numbers) {
for (let i = 1; i < numbers.length; i++) {
const diff = Math.abs(numbers[i] - numbers[i - 1]);
if (diff < 1 || diff > 3) {
return false;
}
}
return true;
}
function isReportSafe(report) {
const numbers = report.split(" ").map((x) => parseInt(x, 10));
if (!areNumbersAllIncreasingOrDecreasing(numbers)) {
return false;
}
if (!areAdjacentNumbersWithinRange(numbers)) {
return false;
}
return true;
}
function isReportSafeAllowRemovingOneNumber(report) {
const numbers = report.split(" ").map((x) => parseInt(x, 10));
function isSafe(numbers) {
return (
areNumbersAllIncreasingOrDecreasing(numbers) &&
areAdjacentNumbersWithinRange(numbers)
);
}
if (isSafe(numbers)) {
return true;
}
// Try removing each number and check if the resulting array is safe
for (let i = 0; i < numbers.length; i++) {
const modifiedNumbers = [...numbers.slice(0, i), ...numbers.slice(i + 1)];
if (isSafe(modifiedNumbers)) {
return true;
}
}
// If no single removal makes the report safe, return false
return false;
}
function part1(input) {
// In the input, each line is a report
const reports = input.split("\n");
// Each report is a string of numbers separated by spaces
let amountOfSafeReports = 0;
reports.forEach((report) => {
if (isReportSafe(report)) {
amountOfSafeReports += 1;
}
});
return amountOfSafeReports;
}
function part2(input) {
// In the input, each line is a report
const reports = input.split("\n");
// Each report is a string of numbers separated by spaces
let amountOfSafeReports = 0;
reports.forEach((report) => {
if (isReportSafeAllowRemovingOneNumber(report)) {
amountOfSafeReports += 1;
}
});
return amountOfSafeReports;
}
test.each([
[
`7 6 4 2 1
1 2 7 8 9
9 7 6 2 1
1 3 2 4 5
8 6 4 4 1
1 3 6 7 9`,
2,
],
[null, 585], // The actual answer
])("Part 1: %s -> %i", (input, expected) => {
const result = part1(input ? input : realData.join("\n"));
expect(result).toBe(expected);
});
test.each([
[
`7 6 4 2 1
1 2 7 8 9
9 7 6 2 1
1 3 2 4 5
8 6 4 4 1
1 3 6 7 9`,
4,
],
[null, 626], // The actual answer
])("Part 2: %s -> %i", (input, expected) => {
const result = part2(input ? input : realData.join("\n"));
expect(result).toBe(expected);
});
});