Prechádzať zdrojové kódy

Saving progress on day 2 part 2

ApisNecros 2 týždňov pred
rodič
commit
5474c0be7f
1 zmenil súbory, kde vykonal 89 pridanie a 58 odobranie
  1. 89 58
      2/2_2.js

+ 89 - 58
2/2_2.js

@@ -1,4 +1,7 @@
-import { loadInput, numericAscSort, strToInt } from "../common.js";
+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);
@@ -16,72 +19,100 @@ function parseInput(inputData) {
 }
 
 /**
- * @param {number[]} parsedInput 
+ * @param {number[][]} parsedInput 
  */
 function solve(parsedInput) {
     let safeReports = 0;
 
     for(const report of parsedInput) {
-        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;
-        /**
-         * The Problem Dampener allows one failed safety meassure
-         */
-        let problemDampenerActive = true;
-
-        // 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) {
-                if (problemDampenerActive) {
-                    problemDampenerActive = false;
-                }
-                else {
-                    safe = false;
-                    break;
-                }
-            }
-            // Make sure the difference wasn't too great
-            else if(difference > 3) {
-                if (problemDampenerActive) {
-                    problemDampenerActive = false;
-                }
-                else {
-                    safe = false;
-                    break;
-                }
-            }
-            else {
-                safe = true;
-            }
+        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);
 
-            lastDirection = currDirection;
+            // 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(safe) { safeReports++; }
+        if(isSafe) { safeReports++; }
     }
 
-    // Not: ^400, ^391
+    // 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];
 }