123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- 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];
- }
|