4 Commits fad1d209d0 ... d5d224a8e5

Author SHA1 Message Date
  ApisNecros d5d224a8e5 Add day 3 part 2 solution 2 weeks ago
  ApisNecros a565255ace Add day 3 part 1 solution 2 weeks ago
  ApisNecros 5474c0be7f Saving progress on day 2 part 2 2 weeks ago
  ApisNecros 30cbe52823 Add deepClone function 2 weeks ago
6 changed files with 158 additions and 58 deletions
  1. 89 58
      2/2_2.js
  2. 24 0
      3/3_1.js
  3. 32 0
      3/3_2.js
  4. 1 0
      3/test.input
  5. 1 0
      3/test_2.input
  6. 11 0
      common.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/test.input", parseInput, true);
 const input = loadInput(2, parseInput);
 const input = loadInput(2, parseInput);
@@ -16,72 +19,100 @@ function parseInput(inputData) {
 }
 }
 
 
 /**
 /**
- * @param {number[]} parsedInput 
+ * @param {number[][]} parsedInput 
  */
  */
 function solve(parsedInput) {
 function solve(parsedInput) {
     let safeReports = 0;
     let safeReports = 0;
 
 
     for(const report of parsedInput) {
     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);
     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];
 }
 }

+ 24 - 0
3/3_1.js

@@ -0,0 +1,24 @@
+import { loadInput } from "../common.js";
+
+// const input = loadInput("./3/test.input", parseInput, true);
+const input = loadInput(3, parseInput);
+
+solve(input);
+
+/**
+ * @param {string} memDump
+ */
+function parseInput(memDump) {
+    return Array.from(memDump.matchAll(/(mul\(\d{1,3},\d{1,3}\))/g));
+}
+
+function solve(validInstructions) {
+    let sum = 0;
+    for(const inst of validInstructions) {
+        sum += eval(inst[0]);
+    }
+
+    console.log("Sum of result of valid instructions:", sum);
+}
+
+function mul(a,b) { return a*b; }

+ 32 - 0
3/3_2.js

@@ -0,0 +1,32 @@
+import { loadInput } from "../common.js";
+
+// const input = loadInput("./3/test_2.input", parseInput, true);
+const input = loadInput(3, parseInput);
+
+solve(input);
+
+/**
+ * @param {string} memDump
+ */
+function parseInput(memDump) {
+    return Array.from(memDump.matchAll(/(?:(do(?:n't)?\(\))|(mul\(\d{1,3},\d{1,3}\)))/g));
+}
+
+function solve(validInstructions) {
+    let sum = 0;
+    let enabled = true;
+    for(const match of validInstructions) {
+        const instruction = match[0];
+
+        if (instruction == "do()") { enabled = true; continue; }
+        else if (instruction == "don't()") { enabled = false; continue; }
+
+        if (enabled) {
+            sum += eval(instruction);
+        }
+    }
+
+    console.log("Sum of result of valid instructions:", sum);
+}
+
+function mul(a,b) { return a*b; }

+ 1 - 0
3/test.input

@@ -0,0 +1 @@
+xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))

+ 1 - 0
3/test_2.input

@@ -0,0 +1 @@
+xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))

+ 11 - 0
common.js

@@ -52,4 +52,15 @@ export function strToInt(string) {
  */
  */
 export function clamp(value, min = -1, max = 1) {
 export function clamp(value, min = -1, max = 1) {
     return Math.max(min, Math.min(max, value));
     return Math.max(min, Math.min(max, value));
+}
+
+/**
+ * Deep clone a value
+ *
+ * @param {any} value
+ *
+ * @returns {any}
+ */
+export function deepClone(value) {
+    return JSON.parse(JSON.stringify(value));
 }
 }