Răsfoiți Sursa

Move common functions into new file

Moved the functions and types needed for both day 3 parts into a common
file.
ApisNecros 1 an în urmă
părinte
comite
7dd6857761
2 a modificat fișierele cu 222 adăugiri și 218 ștergeri
  1. 2 218
      3/3_1.ts
  2. 220 0
      3/3_common.ts

+ 2 - 218
3/3_1.ts

@@ -1,40 +1,5 @@
-import { Inspect, LoadInput } from "../common.ts";
-
-/* Directions */
-const Directions = {
-    NORTH: {
-        X: 0,
-        Y: -1,
-    },
-    SOUTH: {
-        X: 0,
-        Y: 1,
-    },
-    EAST: {
-        X: 1,
-        Y: 0,
-    },
-    WEST: {
-        X: -1,
-        Y: 0,
-    },
-    NORTH_EAST: {
-        X: 1,
-        Y: -1,
-    },
-    NORTH_WEST: {
-        X: -1,
-        Y: -1,
-    },
-    SOUTH_EAST: {
-        X: 1,
-        Y: 1,
-    },
-    SOUTH_WEST: {
-        X: -1,
-        Y: 1,
-    },
-}
+import { LoadInput } from "../common.ts";
+import { BuildSchematicsMap, ParseSchematics, ValidateEngineParts } from "./3_common.ts";
 
 const tests = [
     "467..114..",
@@ -81,186 +46,5 @@ engineParts = ValidateEngineParts(engineParts, schematics);
 const sumOfPartNumbers = engineParts.reduce((accumulator, part) => accumulator += part.PartNumber, 0);
 console.log(`The sum of part numbers is: ${sumOfPartNumbers}`);
 
-/**
- * Parse the schematics to find all possible Engine Parts
- * @param {string[][]} schematicsMap A 2D grid of characters making up a schematic
- * @returns {EnginePart[]} An array of potential Engine Parts
- */
-function ParseSchematics(schematicsMap: string[][]): EnginePart[] {
-    const engineParts: EnginePart[] = [];
-
-    /** The current pointer within the schematics' 2D array */
-    const schematicsPointer: Vector2 = {
-        X: 0,
-        Y: 0,
-    };
-
-    for(; schematicsPointer.Y < schematicsMap.length; schematicsPointer.Y++) {
-        // Reset the X pointer each line
-        schematicsPointer.X = 0;
-        /** A line from the total schematics */
-        const schematicsLine = schematicsMap[schematicsPointer.Y];
-
-        // Create a reusable EnginePart store
-        let part: EnginePart|null = null;
-
-        for(; schematicsPointer.X < schematicsMap[schematicsPointer.Y].length; schematicsPointer.X++) {
-            const char = schematicsMap[schematicsPointer.Y][schematicsPointer.X];
-
-            // Check if the current character is a number
-            if (/\d/.test(char)) {
-                // Check if our EnginePart store is initialized
-                if (part == null) { part = { PartNumber: 0, Coordinates: [] }; }
-
-                if (part.PartNumber) {
-                    // Concatenate the number to the existing part of the Part Number
-                    part.PartNumber = Number("" + part.PartNumber + char);
-                }
-                else {
-                    // Start the new Part Number
-                    part.PartNumber = Number(char);
-                }
-
-                // Push the coordinates
-                part.Coordinates.push({
-                    X: schematicsPointer.X,
-                    Y: schematicsPointer.Y,
-                });
-            }
-            // If it's not
-            else {
-                // Check if the EnginePart store has a value
-                if(part != null) {
-                    // If it does, store it and empty it
-                    engineParts.push(part);
-                    part = null;
-                }
-            }
-        }
-
-        if(part !== null) {
-            engineParts.push(part);
-        }
-    }
-
-    return engineParts;
-}
-
-/**
- * Validates all previously parsed Engine Parts
- *
- * An Engine Part is only valid if it's connected, even diagonally, to a
- * symbol other than `.`.
- *
- * @param {EnginePart[]} potentialParts All potential Engine Parts
- * @param {string[][]} schematicsMap A 2D grid of characters making up a schematic
- * @returns {EnginePart[]} A filtered list of all valid Engine Parts
- */
-function ValidateEngineParts(potentialParts: EnginePart[], schematicsMap: string[][]): EnginePart[] {
-    const validParts: EnginePart[] = [];
-
-    for (const part of potentialParts) {
-        let symbolFound = false;
-        for (const point of part.Coordinates) {
-            if (BordersASymbol(point, schematicsMap)) {
-                symbolFound = true;
-                validParts.push(part);
-                break;
-            }
-        }
-        if (!symbolFound) {
-            console.log("No symbol found for the following part:");
-            Inspect(part);
-        }
-    }
-    return validParts;
-}
-
-/**
- * Check if a point on the schematics map borders a symbol
- *
- * A symbol is any character other than a digit or a period.
- *
- * @param point A point on the schematics map
- * @param schematicsMap A 2D grid of characters making up a schematic
- * @returns {boolean} Whether the point borders a symbol or not
- */
-function BordersASymbol(point: Vector2, schematicsMap: string[][]): boolean {
-    // Initialize all border chars as NOPs
-    let northernBorder   =  ".";
-    let easternBorder    =  ".";
-    let southernBorder   =  ".";
-    let westernBorder    =  ".";
-    let northEastBorder  =  ".";
-    let northWestBorder  =  ".";
-    let southEastBorder  =  ".";
-    let southWestBorder  =  ".";
-    // Check what borders exist
-    const northExists = !!schematicsMap[point.Y + Directions.NORTH.Y];
-    const southExists = !!schematicsMap[point.Y + Directions.SOUTH.Y];
-    const eastExists = !!schematicsMap[point.Y][point.X + Directions.EAST.X];
-    const westExists = !!schematicsMap[point.Y][point.X + Directions.WEST.X];
-    // Find the border chars
-    if(northExists) {
-        northernBorder = schematicsMap[point.Y + Directions.NORTH.Y][point.X + Directions.NORTH.X];
-        if(eastExists) {
-            northEastBorder = schematicsMap[point.Y + Directions.NORTH_EAST.Y][point.X + Directions.NORTH_EAST.X];
-        }
-        if(westExists) {
-            northWestBorder = schematicsMap[point.Y + Directions.NORTH_WEST.Y][point.X + Directions.NORTH_WEST.X];
-        }
-    }
-    if(southExists) {
-        southernBorder = schematicsMap[point.Y + Directions.SOUTH.Y][point.X + Directions.SOUTH.X];
-        if(eastExists) {
-            southEastBorder = schematicsMap[point.Y + Directions.SOUTH_EAST.Y][point.X + Directions.SOUTH_EAST.X];
-        }
-        if(westExists) {
-            southWestBorder = schematicsMap[point.Y + Directions.SOUTH_WEST.Y][point.X + Directions.SOUTH_WEST.X];
-        }
-    }
-    if (eastExists) {
-        easternBorder = schematicsMap[point.Y + Directions.EAST.Y][point.X + Directions.EAST.X];
-    }
-    if (westExists) {
-        westernBorder = schematicsMap[point.Y + Directions.WEST.Y][point.X + Directions.WEST.X];
-    }
-    // Combine all bordering characters into one long string
-    const allBorders = northernBorder + easternBorder + southernBorder + westernBorder + northEastBorder + northWestBorder + southEastBorder + southWestBorder;
-
-    return /[^0-9\.]/.test(allBorders);
-}
 
-/**
- * Split the schematics into a 2D grid of characters
- *
- * @param {string[]} schematics The array of lines from the schematics
- * @returns {string[][]} A 2D grid of characters
- */
-function BuildSchematicsMap(schematics: string[]): string[][] {
-    return schematics.map((schematicsLine) => schematicsLine.split(''));
-}
 
-/**
- * An engine part
- */
-type EnginePart = {
-    PartNumber: number,
-    Coordinates: Vector2[],
-};
-
-/**
- * A symbol on the schematics map
- */
-type SchematicsSymbol = {
-    Symbol: string,
-    Coordinates: Vector2,
-};
-
-/**
- * A position within a 2D grid
- */
-type Vector2 = {
-    X: number,
-    Y: number,
-};

+ 220 - 0
3/3_common.ts

@@ -0,0 +1,220 @@
+import { Inspect } from "../common.ts";
+/* Directions */
+const Directions = {
+    NORTH: {
+        X: 0,
+        Y: -1,
+    },
+    SOUTH: {
+        X: 0,
+        Y: 1,
+    },
+    EAST: {
+        X: 1,
+        Y: 0,
+    },
+    WEST: {
+        X: -1,
+        Y: 0,
+    },
+    NORTH_EAST: {
+        X: 1,
+        Y: -1,
+    },
+    NORTH_WEST: {
+        X: -1,
+        Y: -1,
+    },
+    SOUTH_EAST: {
+        X: 1,
+        Y: 1,
+    },
+    SOUTH_WEST: {
+        X: -1,
+        Y: 1,
+    },
+}
+
+/**
+ * Parse the schematics to find all possible Engine Parts
+ * @param {string[][]} schematicsMap A 2D grid of characters making up a schematic
+ * @returns {EnginePart[]} An array of potential Engine Parts
+ */
+export function ParseSchematics(schematicsMap: string[][]): EnginePart[] {
+    const engineParts: EnginePart[] = [];
+
+    /** The current pointer within the schematics' 2D array */
+    const schematicsPointer: Vector2 = {
+        X: 0,
+        Y: 0,
+    };
+
+    for(; schematicsPointer.Y < schematicsMap.length; schematicsPointer.Y++) {
+        // Reset the X pointer each line
+        schematicsPointer.X = 0;
+        /** A line from the total schematics */
+        const schematicsLine = schematicsMap[schematicsPointer.Y];
+
+        // Create a reusable EnginePart store
+        let part: EnginePart|null = null;
+
+        for(; schematicsPointer.X < schematicsMap[schematicsPointer.Y].length; schematicsPointer.X++) {
+            const char = schematicsMap[schematicsPointer.Y][schematicsPointer.X];
+
+            // Check if the current character is a number
+            if (/\d/.test(char)) {
+                // Check if our EnginePart store is initialized
+                if (part == null) { part = { PartNumber: 0, Coordinates: [] }; }
+
+                if (part.PartNumber) {
+                    // Concatenate the number to the existing part of the Part Number
+                    part.PartNumber = Number("" + part.PartNumber + char);
+                }
+                else {
+                    // Start the new Part Number
+                    part.PartNumber = Number(char);
+                }
+
+                // Push the coordinates
+                part.Coordinates.push({
+                    X: schematicsPointer.X,
+                    Y: schematicsPointer.Y,
+                });
+            }
+            // If it's not
+            else {
+                // Check if the EnginePart store has a value
+                if(part != null) {
+                    // If it does, store it and empty it
+                    engineParts.push(part);
+                    part = null;
+                }
+            }
+        }
+
+        if(part !== null) {
+            engineParts.push(part);
+        }
+    }
+
+    return engineParts;
+}
+
+/**
+ * Validates all previously parsed Engine Parts
+ *
+ * An Engine Part is only valid if it's connected, even diagonally, to a
+ * symbol other than `.`.
+ *
+ * @param {EnginePart[]} potentialParts All potential Engine Parts
+ * @param {string[][]} schematicsMap A 2D grid of characters making up a schematic
+ * @returns {EnginePart[]} A filtered list of all valid Engine Parts
+ */
+export function ValidateEngineParts(potentialParts: EnginePart[], schematicsMap: string[][]): EnginePart[] {
+    const validParts: EnginePart[] = [];
+
+    for (const part of potentialParts) {
+        let symbolFound = false;
+        for (const point of part.Coordinates) {
+            if (BordersASymbol(point, schematicsMap)) {
+                symbolFound = true;
+                validParts.push(part);
+                break;
+            }
+        }
+        if (!symbolFound) {
+            console.log("No symbol found for the following part:");
+            Inspect(part);
+        }
+    }
+    return validParts;
+}
+
+/**
+* Check if a point on the schematics map borders a symbol
+*
+* A symbol is any character other than a digit or a period.
+*
+* @param point A point on the schematics map
+* @param schematicsMap A 2D grid of characters making up a schematic
+* @returns {boolean} Whether the point borders a symbol or not
+*/
+export function BordersASymbol(point: Vector2, schematicsMap: string[][]): boolean {
+   // Initialize all border chars as NOPs
+   let northernBorder   =  ".";
+   let easternBorder    =  ".";
+   let southernBorder   =  ".";
+   let westernBorder    =  ".";
+   let northEastBorder  =  ".";
+   let northWestBorder  =  ".";
+   let southEastBorder  =  ".";
+   let southWestBorder  =  ".";
+   // Check what borders exist
+   const northExists = !!schematicsMap[point.Y + Directions.NORTH.Y];
+   const southExists = !!schematicsMap[point.Y + Directions.SOUTH.Y];
+   const eastExists = !!schematicsMap[point.Y][point.X + Directions.EAST.X];
+   const westExists = !!schematicsMap[point.Y][point.X + Directions.WEST.X];
+   // Find the border chars
+   if(northExists) {
+       northernBorder = schematicsMap[point.Y + Directions.NORTH.Y][point.X + Directions.NORTH.X];
+       if(eastExists) {
+           northEastBorder = schematicsMap[point.Y + Directions.NORTH_EAST.Y][point.X + Directions.NORTH_EAST.X];
+       }
+       if(westExists) {
+           northWestBorder = schematicsMap[point.Y + Directions.NORTH_WEST.Y][point.X + Directions.NORTH_WEST.X];
+       }
+   }
+   if(southExists) {
+       southernBorder = schematicsMap[point.Y + Directions.SOUTH.Y][point.X + Directions.SOUTH.X];
+       if(eastExists) {
+           southEastBorder = schematicsMap[point.Y + Directions.SOUTH_EAST.Y][point.X + Directions.SOUTH_EAST.X];
+       }
+       if(westExists) {
+           southWestBorder = schematicsMap[point.Y + Directions.SOUTH_WEST.Y][point.X + Directions.SOUTH_WEST.X];
+       }
+   }
+   if (eastExists) {
+       easternBorder = schematicsMap[point.Y + Directions.EAST.Y][point.X + Directions.EAST.X];
+   }
+   if (westExists) {
+       westernBorder = schematicsMap[point.Y + Directions.WEST.Y][point.X + Directions.WEST.X];
+   }
+   // Combine all bordering characters into one long string
+   const allBorders = northernBorder + easternBorder + southernBorder + westernBorder + northEastBorder + northWestBorder + southEastBorder + southWestBorder;
+
+   return /[^0-9\.]/.test(allBorders);
+}
+
+/**
+ * Split the schematics into a 2D grid of characters
+ *
+ * @param {string[]} schematics The array of lines from the schematics
+ * @returns {string[][]} A 2D grid of characters
+ */
+export function BuildSchematicsMap(schematics: string[]): string[][] {
+    return schematics.map((schematicsLine) => schematicsLine.split(''));
+}
+
+/**
+ * An engine part
+ */
+export type EnginePart = {
+    PartNumber: number,
+    Coordinates: Vector2[],
+};
+
+/**
+ * A symbol on the schematics map
+ */
+export type SchematicsSymbol = {
+    Symbol: string,
+    Coordinates: Vector2,
+};
+
+/**
+ * A position within a 2D grid
+ */
+export type Vector2 = {
+    X: number,
+    Y: number,
+};