Explorar el Código

Add day 8 part i solution

ApisNecros hace 1 año
padre
commit
fdd6bc5f20
Se han modificado 1 ficheros con 102 adiciones y 0 borrados
  1. 102 0
      8/8_1.ts

+ 102 - 0
8/8_1.ts

@@ -0,0 +1,102 @@
+import { LoadInput } from "../common.ts";
+
+const tests_EZ = [
+    "RL",
+    "",
+    "AAA = (BBB, CCC)",
+    "BBB = (DDD, EEE)",
+    "CCC = (ZZZ, GGG)",
+    "DDD = (DDD, DDD)",
+    "EEE = (EEE, EEE)",
+    "GGG = (GGG, GGG)",
+    "ZZZ = (ZZZ, ZZZ)",
+];
+
+const tests_longer = [
+    "LLR",
+    "",
+    "AAA = (BBB, BBB)",
+    "BBB = (AAA, ZZZ)",
+    "ZZZ = (ZZZ, ZZZ)",
+];
+
+const START_NODE: keyof MapNodeTree = "AAA";
+const END_NODE: keyof MapNodeTree = "ZZZ";
+
+const input = await LoadInput(8);
+
+const [directions, map] = ParseMap(input);
+
+let nodeID: keyof MapNodeTree|undefined = START_NODE;
+let stepsTaken = 0;
+
+while (nodeID = GetNextNodeInMap(directions, map, nodeID, stepsTaken)) {
+    stepsTaken++;
+    if (nodeID == END_NODE) {
+        break;
+    }
+}
+
+console.log(`A total of ${stepsTaken} steps were taken`);
+
+/**
+ * Parse the input into a string of directions and a list of nodes and their child nodes
+ *
+ * @param {string[]} map The array of lines representing the map
+ * @returns {[string, MapNodeTree]} A string of the directions to take and the node tree for the map
+ */
+function ParseMap(map: string[]): [string, MapNodeTree] {
+    const tree: MapNodeTree = {};
+    const directions = map.shift() || "";
+    // Discard empty line
+    map.shift();
+
+    let nodeLine:string|undefined = "";
+    while(nodeLine = map.shift()) {
+        const [id, leftNode, rightNode] = Array.from(nodeLine.matchAll(/(\w{3})/g), (match) => match[1]);
+
+        if (!id || !leftNode || !rightNode) {
+            throw new Error(`Failed to parse line: ${nodeLine}\n\tid: ${id}\n\tleftNode: ${leftNode}\n\trightNode: ${rightNode}`);
+        }
+
+        tree[id] = {L: leftNode, R: rightNode};
+    }
+
+    return [directions, tree];
+}
+
+/**
+ * Find the ID of the next node to visit
+ *
+ * @param {string} directions The entire string of directions
+ * @param {MapNodeTree} map A list of nodes and their child nodes
+ * @param {keyof MapNodeTree} currentNode The ID of the node we're current at
+ * @param {number} stepsTaken The amount of steps already taken in the trek
+ * @returns {keyof MapNodeTree|undefined} The next node ID, or undefined if none was found
+ */
+function GetNextNodeInMap(directions: string, map: MapNodeTree, currentNode: keyof MapNodeTree, stepsTaken: number): keyof MapNodeTree|undefined {
+    let nextNodeID: keyof MapNodeTree|undefined = undefined;
+
+    // Ensure the current node exists
+    if (map[currentNode]) {
+        // Get the next direction to travel in as a looping index of the directions string
+        const nextDirection = directions[stepsTaken % directions.length] as "L"|"R";
+        // Store the next node ID
+        nextNodeID = map[currentNode][nextDirection];
+    }
+
+    return nextNodeID;
+}
+
+/**
+ * An object representing a tree of nodes
+ */
+type MapNodeTree = {
+    /** The ID of the node */
+    [NodeID: string]: {
+        /** The ID of the node to the left of this one */
+        L: string,
+        /** The ID of the node to the right of this one */
+        R: string,
+    },
+};