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