Selaa lähdekoodia

Move day 5 common functions to file

ApisNecros 1 vuosi sitten
vanhempi
säilyke
6a2efb20df
2 muutettua tiedostoa jossa 218 lisäystä ja 216 poistoa
  1. 2 216
      5/5_1.ts
  2. 216 0
      5/5_common.ts

+ 2 - 216
5/5_1.ts

@@ -1,4 +1,5 @@
-import { ExtractNumbers, Inspect, LoadInput } from "../common.ts";
+import { LoadInput } from "../common.ts";
+import { ParseInput, MapSeed, isSeedMapArray } from "./5_common.ts"
 
 const tests = [
     "seeds: 79 14 55 13",
@@ -53,218 +54,3 @@ if (isSeedMapArray(seeds)) {
 }
 
 console.log(`The lowest location ID found is: ${closestLocationID}`);
-
-function ParseInput(almanac: string[]): RangeMaps {
-    /** An empty initializer for our output */
-    const output: RangeMaps = {
-        Seeds: [],
-        SeedToSoil: [],
-        SoilToFertilizer: [],
-        FertilizerToWater: [],
-        WaterToLight: [],
-        LightToTemperature: [],
-        TemperatureToHumidity: [],
-        HumidityToLocation: [],
-    };
-
-    for (let i = 0; i < almanac.length; i++) {
-        let line = almanac[i];
-
-        // Parse the seed ID's
-        if (/^seeds:/.test(line)) {
-            // Extract all numbers from the line
-            const seedIDs = ExtractNumbers(line);
-            // Add to the output's Seeds array a new Seed for each number
-            seedIDs.forEach((id) => { output.Seeds.push(id); });
-            // Skip the next blank
-            i++;
-        }
-        // Parse the Seed to Soil ranges
-        else if (/^seed\-to/.test(line)) {
-            output.SeedToSoil = ParseSourceDestinationRange(++i, almanac);
-        }
-        // Parse the Soil to Fertilizer ranges
-        else if (/^soil\-to/.test(line)) {
-            output.SoilToFertilizer = ParseSourceDestinationRange(++i, almanac);
-        }
-        // Parse the Fertilizer to Water ranges
-        else if (/^fertilizer\-to/.test(line)) {
-            output.FertilizerToWater = ParseSourceDestinationRange(++i, almanac);
-        }
-        // Parse the Water to Light ranges
-        else if (/^water\-to/.test(line)) {
-            output.WaterToLight = ParseSourceDestinationRange(++i, almanac);
-        }
-        // Parse the Light to Temperature ranges
-        else if (/^light\-to/.test(line)) {
-            output.LightToTemperature = ParseSourceDestinationRange(++i, almanac);
-        }
-        // Parse the Temperature to Humidity ranges
-        else if (/^temperature\-to/.test(line)) {
-            output.TemperatureToHumidity = ParseSourceDestinationRange(++i, almanac);
-        }
-        // Parse the Humidity to Location ranges
-        else if (/^humidity\-to/.test(line)) {
-            output.HumidityToLocation = ParseSourceDestinationRange(++i, almanac);
-        }
-    }
-
-    return output;
-}
-
-/**
- * Helper function to parse the ranges for each mappable section
- *
- * @param {number} lineNumber The line number to begin parsing from
- * @param {string[]} almanac The complete almanac
- * @returns {RangeMap[]} A list of mapped indices
- */
-function ParseSourceDestinationRange(lineNumber: number, almanac: string[]): RangeMap[] {
-    const rangeMap: RangeMap[] = [];
-    do {
-        // Get the values out of the line
-        const [destinationRangeStart, sourceRangeStart, rangeLength] = ExtractNumbers(almanac[lineNumber]);
-        
-        rangeMap.push({
-            SourceRanges: {
-                Start: sourceRangeStart,
-                End: sourceRangeStart + rangeLength - 1,
-            },
-            DestinationRange: {
-                Start: destinationRangeStart,
-                End: destinationRangeStart + rangeLength - 1,
-            }
-        });
-    } while(almanac[++lineNumber]);
-    
-    return rangeMap;
-}
-
-/**
- * Maps one object to another based on ID ranges
- *
- * If the ID given doesn't fit in any of the ranges given, then the
- * input is returned
- *
- * @param {number} needle The ID number to find
- * @param {RangeMap[]} haystack The list of ranges to find the ID in
- * @returns {number} The ID of the mapped object
- */
-function MapObjectByID(needle: number, haystack: RangeMap[]): number {
-    for (const range of haystack) {
-        if (range.SourceRanges.Start <= needle && range.SourceRanges.End >= needle) {
-            return range.DestinationRange.Start + (needle - range.SourceRanges.Start);
-        }
-    }
-    return needle;
-}
-
-/**
- * Map a Seed ID to all of its other attributes
- *
- * Given a seed ID, finds its soil type, fertilizer type, water type,
- * light type, temperature type, humidity type, and location ID.
- *
- * @param {number} seedID 
- * @param {RangeMaps} rangeMaps A parsed map of ranges
- * @returns 
- */
-function MapSeed(seedID: number, rangeMaps: RangeMaps): SeedMap|undefined {
-    // Make sure the seed with that ID exists before continueing
-    if(!rangeMaps.Seeds.includes(seedID)) { return undefined; }
-    
-    // Initialize our seed map object
-    const seed: SeedMap = {
-        ID: seedID,
-        SoilID: 0,
-        FertilizerID: 0,
-        WaterID: 0,
-        LightID: 0,
-        TemperatureID: 0,
-        HumidityID: 0,
-        LocationID: 0,
-    };
-
-    seed.SoilID =        MapObjectByID(seedID, rangeMaps.SeedToSoil);
-    seed.FertilizerID =  MapObjectByID(seed.SoilID, rangeMaps.SoilToFertilizer);
-    seed.WaterID =       MapObjectByID(seed.FertilizerID, rangeMaps.FertilizerToWater);
-    seed.LightID =       MapObjectByID(seed.WaterID, rangeMaps.WaterToLight);
-    seed.TemperatureID = MapObjectByID(seed.LightID, rangeMaps.LightToTemperature);
-    seed.HumidityID =    MapObjectByID(seed.TemperatureID, rangeMaps.TemperatureToHumidity);
-    seed.LocationID =    MapObjectByID(seed.HumidityID, rangeMaps.HumidityToLocation);
-
-    return seed;
-}
-
-/**
- * Type guard function to ensure an array is an array of SeedMaps
- *
- * @param {any[]} valueArray The array to check
- * @returns {boolean} Whether the input is an array of SeedMaps or not
- */
-function isSeedMapArray(valueArray: any[]): valueArray is SeedMap[] {
-    const value = valueArray.shift();
-
-    if (!value || typeof value !== "object") { return false; }
-
-    return Object.hasOwn(value, "ID")
-        && Object.hasOwn(value, "SoilID")
-        && Object.hasOwn(value, "FertilizerID")
-        && Object.hasOwn(value, "WaterID")
-        && Object.hasOwn(value, "LightID")
-        && Object.hasOwn(value, "TemperatureID")
-        && Object.hasOwn(value, "HumidityID")
-        && Object.hasOwn(value, "LocationID");
-}
-
-type IDRange = {
-    Start: number,
-    End: number,
-};
-
-/** An IdentifiableObject that points to another IdentifiableObject */
-type RangeMap = {
-    /** The ID that this object points to */
-    SourceRanges: IDRange,
-    DestinationRange: IDRange,
-};
-
-/** A complete map of all object IDs and where they point to */
-type RangeMaps = {
-    /** The list of seed IDs */
-    Seeds: number[],
-    /** The map of seed to soil IDs */
-    SeedToSoil: RangeMap[],
-    /** The map of soil to fertilizer IDs */
-    SoilToFertilizer: RangeMap[],
-    /** The map of fertilizer to water IDs */
-    FertilizerToWater: RangeMap[],
-    /** The map of water to light IDs */
-    WaterToLight: RangeMap[],
-    /** The map of light to temperature IDs */
-    LightToTemperature: RangeMap[],
-    /** The map of temperature to humidity IDs */
-    TemperatureToHumidity: RangeMap[],
-    /** The map of humidity to location IDs */
-    HumidityToLocation: RangeMap[],
-}
-
-/** A completed map of a seed's property IDs */
-type SeedMap = {
-    /** The ID of the seed */
-    ID: number,
-    /** The ID of the soil type the seed needs planted in */
-    SoilID: number,
-    /** The ID of the fertilizer type the soil needs */
-    FertilizerID: number,
-    /** The ID of the water type the fertilizer needs */
-    WaterID: number,
-    /** The ID of the light type the water needs */
-    LightID: number,
-    /** The ID of the temperature type the light needs */
-    TemperatureID: number,
-    /** The ID of the humidity type the temperature needs */
-    HumidityID: number,
-    /** The ID of the location the humidity needs */
-    LocationID: number,
-}

+ 216 - 0
5/5_common.ts

@@ -0,0 +1,216 @@
+import { ExtractNumbers } from "../common.ts";
+
+export function ParseInput(almanac: string[]): RangeMaps {
+    /** An empty initializer for our output */
+    const output: RangeMaps = {
+        Seeds: [],
+        SeedToSoil: [],
+        SoilToFertilizer: [],
+        FertilizerToWater: [],
+        WaterToLight: [],
+        LightToTemperature: [],
+        TemperatureToHumidity: [],
+        HumidityToLocation: [],
+    };
+
+    for (let i = 0; i < almanac.length; i++) {
+        let line = almanac[i];
+
+        // Parse the seed ID's
+        if (/^seeds:/.test(line)) {
+            // Extract all numbers from the line
+            const seedIDs = ExtractNumbers(line);
+            // Add to the output's Seeds array a new Seed for each number
+            seedIDs.forEach((id) => { output.Seeds.push(id); });
+            // Skip the next blank
+            i++;
+        }
+        // Parse the Seed to Soil ranges
+        else if (/^seed\-to/.test(line)) {
+            output.SeedToSoil = ParseSourceDestinationRange(++i, almanac);
+        }
+        // Parse the Soil to Fertilizer ranges
+        else if (/^soil\-to/.test(line)) {
+            output.SoilToFertilizer = ParseSourceDestinationRange(++i, almanac);
+        }
+        // Parse the Fertilizer to Water ranges
+        else if (/^fertilizer\-to/.test(line)) {
+            output.FertilizerToWater = ParseSourceDestinationRange(++i, almanac);
+        }
+        // Parse the Water to Light ranges
+        else if (/^water\-to/.test(line)) {
+            output.WaterToLight = ParseSourceDestinationRange(++i, almanac);
+        }
+        // Parse the Light to Temperature ranges
+        else if (/^light\-to/.test(line)) {
+            output.LightToTemperature = ParseSourceDestinationRange(++i, almanac);
+        }
+        // Parse the Temperature to Humidity ranges
+        else if (/^temperature\-to/.test(line)) {
+            output.TemperatureToHumidity = ParseSourceDestinationRange(++i, almanac);
+        }
+        // Parse the Humidity to Location ranges
+        else if (/^humidity\-to/.test(line)) {
+            output.HumidityToLocation = ParseSourceDestinationRange(++i, almanac);
+        }
+    }
+
+    return output;
+}
+
+/**
+ * Helper function to parse the ranges for each mappable section
+ *
+ * @param {number} lineNumber The line number to begin parsing from
+ * @param {string[]} almanac The complete almanac
+ * @returns {RangeMap[]} A list of mapped indices
+ */
+export function ParseSourceDestinationRange(lineNumber: number, almanac: string[]): RangeMap[] {
+    const rangeMap: RangeMap[] = [];
+    do {
+        // Get the values out of the line
+        const [destinationRangeStart, sourceRangeStart, rangeLength] = ExtractNumbers(almanac[lineNumber]);
+        
+        rangeMap.push({
+            SourceRanges: {
+                Start: sourceRangeStart,
+                End: sourceRangeStart + rangeLength - 1,
+            },
+            DestinationRange: {
+                Start: destinationRangeStart,
+                End: destinationRangeStart + rangeLength - 1,
+            }
+        });
+    } while(almanac[++lineNumber]);
+    
+    return rangeMap;
+}
+
+/**
+ * Maps one object to another based on ID ranges
+ *
+ * If the ID given doesn't fit in any of the ranges given, then the
+ * input is returned
+ *
+ * @param {number} needle The ID number to find
+ * @param {RangeMap[]} haystack The list of ranges to find the ID in
+ * @returns {number} The ID of the mapped object
+ */
+export function MapObjectByID(needle: number, haystack: RangeMap[]): number {
+    for (const range of haystack) {
+        if (range.SourceRanges.Start <= needle && range.SourceRanges.End >= needle) {
+            return range.DestinationRange.Start + (needle - range.SourceRanges.Start);
+        }
+    }
+    return needle;
+}
+
+/**
+ * Map a Seed ID to all of its other attributes
+ *
+ * Given a seed ID, finds its soil type, fertilizer type, water type,
+ * light type, temperature type, humidity type, and location ID.
+ *
+ * @param {number} seedID 
+ * @param {RangeMaps} rangeMaps A parsed map of ranges
+ * @returns 
+ */
+export function MapSeed(seedID: number, rangeMaps: RangeMaps): SeedMap|undefined {
+    // Make sure the seed with that ID exists before continueing
+    if(!rangeMaps.Seeds.includes(seedID)) { return undefined; }
+    
+    // Initialize our seed map object
+    const seed: SeedMap = {
+        ID: seedID,
+        SoilID: 0,
+        FertilizerID: 0,
+        WaterID: 0,
+        LightID: 0,
+        TemperatureID: 0,
+        HumidityID: 0,
+        LocationID: 0,
+    };
+
+    seed.SoilID =        MapObjectByID(seedID, rangeMaps.SeedToSoil);
+    seed.FertilizerID =  MapObjectByID(seed.SoilID, rangeMaps.SoilToFertilizer);
+    seed.WaterID =       MapObjectByID(seed.FertilizerID, rangeMaps.FertilizerToWater);
+    seed.LightID =       MapObjectByID(seed.WaterID, rangeMaps.WaterToLight);
+    seed.TemperatureID = MapObjectByID(seed.LightID, rangeMaps.LightToTemperature);
+    seed.HumidityID =    MapObjectByID(seed.TemperatureID, rangeMaps.TemperatureToHumidity);
+    seed.LocationID =    MapObjectByID(seed.HumidityID, rangeMaps.HumidityToLocation);
+
+    return seed;
+}
+
+/**
+ * Type guard function to ensure an array is an array of SeedMaps
+ *
+ * @param {any[]} valueArray The array to check
+ * @returns {boolean} Whether the input is an array of SeedMaps or not
+ */
+export function isSeedMapArray(valueArray: any[]): valueArray is SeedMap[] {
+    const value = valueArray.shift();
+
+    if (!value || typeof value !== "object") { return false; }
+
+    return Object.hasOwn(value, "ID")
+        && Object.hasOwn(value, "SoilID")
+        && Object.hasOwn(value, "FertilizerID")
+        && Object.hasOwn(value, "WaterID")
+        && Object.hasOwn(value, "LightID")
+        && Object.hasOwn(value, "TemperatureID")
+        && Object.hasOwn(value, "HumidityID")
+        && Object.hasOwn(value, "LocationID");
+}
+
+export type IDRange = {
+    Start: number,
+    End: number,
+};
+
+/** An IdentifiableObject that points to another IdentifiableObject */
+export type RangeMap = {
+    /** The ID that this object points to */
+    SourceRanges: IDRange,
+    DestinationRange: IDRange,
+};
+
+/** A complete map of all object IDs and where they point to */
+export type RangeMaps = {
+    /** The list of seed IDs */
+    Seeds: number[],
+    /** The map of seed to soil IDs */
+    SeedToSoil: RangeMap[],
+    /** The map of soil to fertilizer IDs */
+    SoilToFertilizer: RangeMap[],
+    /** The map of fertilizer to water IDs */
+    FertilizerToWater: RangeMap[],
+    /** The map of water to light IDs */
+    WaterToLight: RangeMap[],
+    /** The map of light to temperature IDs */
+    LightToTemperature: RangeMap[],
+    /** The map of temperature to humidity IDs */
+    TemperatureToHumidity: RangeMap[],
+    /** The map of humidity to location IDs */
+    HumidityToLocation: RangeMap[],
+}
+
+/** A completed map of a seed's property IDs */
+export type SeedMap = {
+    /** The ID of the seed */
+    ID: number,
+    /** The ID of the soil type the seed needs planted in */
+    SoilID: number,
+    /** The ID of the fertilizer type the soil needs */
+    FertilizerID: number,
+    /** The ID of the water type the fertilizer needs */
+    WaterID: number,
+    /** The ID of the light type the water needs */
+    LightID: number,
+    /** The ID of the temperature type the light needs */
+    TemperatureID: number,
+    /** The ID of the humidity type the temperature needs */
+    HumidityID: number,
+    /** The ID of the location the humidity needs */
+    LocationID: number,
+}