import { deepClone, loadInput, numericAscSort, strToInt } from "../common.js"; /** junk variable to hold junk */ let _; // const input = loadInput("./2/test.input", parseInput, true); const input = loadInput(2, parseInput); solve(input); /** * @param {string} inputData * @returns {number[]} */ function parseInput(inputData) { const reports = inputData.split(/\n/).map((report) => report.split(" ").map(strToInt)); return reports; } /** * @param {number[][]} parsedInput */ function solve(parsedInput) { let safeReports = 0; for(const report of parsedInput) { let [isSafe, unsafeIndex] = isReportSafe(report); // If the report isn't safe, try removing the first unsafe value, and check again if(!isSafe) { console.warn("Report wasn't safe. Checking other variations"); // Clone the report so we don't affect the original array let reportClone = deepClone(report); // Remove the potentially unsafe index reportClone.splice(unsafeIndex, 1); console.warn("Trying modified report: ", reportClone); // Test its safety [isSafe, _] = isReportSafe(reportClone); // If that one is still unsafe, try removing the value to the right of the unsafe index, and try again if(!isSafe) { reportClone = deepClone(report); reportClone.splice(unsafeIndex + 1, 1); console.warn("Trying modified report: ", reportClone); [isSafe, _] = isReportSafe(reportClone); } console.log(); } if(isSafe) { safeReports++; } } // Not: v420, v424, !435, ^500 console.log("Safe Reports:", safeReports); } /** * Check if a given report is safe * * If the report is deemed unsafe, the first unsafe index will be returned along with * the safe boolean. * * @param {number[]} report The report to check * * @returns {array} A two-index array containing a boolean of whether the report is safe or not, * and the index of the unsafe value if */ function isReportSafe(report) { let currDirection = 0; let lastDirection = 0; /** * Whether or not the report is safe * * Report is only safe when the data is sorted in one direction, and * each value is no less than 1 value away, and no more than 3 values * away from each other. * * e.g. * ``` * 1,2,3,4,5 safe * 5,4,3,2,1 safe * 1,2,3,2,1 unsafe * 1,2,4,5,6 safe * 1,2,7,8,9 unsafe * ``` */ let safe = false; let unsafeLevel = null; // Safety check written this way to make troubleshooting easier for(let i = 0; i < report.length - 1; i++) { currDirection = numericAscSort(report[i], report[i + 1]); const difference = Math.abs(report[i] - report[i + 1]); // Check if the direction has changed, but skip the first round // Also catches if there were no differences between the two numbers if(i != 0 && lastDirection != currDirection) { unsafeLevel = i; safe = false; break; } // Make sure the difference wasn't too great else if(difference > 3) { unsafeLevel = i; safe = false; break; } else { safe = true; } lastDirection = currDirection; } return [safe, unsafeLevel]; }