Переглянути джерело

Add beginning to day 5 part i

ApisNecros 1 рік тому
батько
коміт
17a3fb6ad1
1 змінених файлів з 158 додано та 0 видалено
  1. 158 0
      5/5_1.ts

+ 158 - 0
5/5_1.ts

@@ -0,0 +1,158 @@
+import { ExtractNumbers, Inspect } from "../common.ts";
+
+const tests = [
+    "seeds: 79 14 55 13",
+    "",
+    "seed-to-soil map:",
+    "50 98 2",
+    "52 50 48",
+    "",
+    "soil-to-fertilizer map:",
+    "0 15 37",
+    "37 52 2",
+    "39 0 15",
+    "",
+    "fertilizer-to-water map:",
+    "49 53 8",
+    "0 11 42",
+    "42 0 7",
+    "57 7 4",
+    "",
+    "water-to-light map:",
+    "88 18 7",
+    "18 25 70",
+    "",
+    "light-to-temperature map:",
+    "45 77 23",
+    "81 45 19",
+    "68 64 13",
+    "",
+    "temperature-to-humidity map:",
+    "0 69 1",
+    "1 0 69",
+    "",
+    "humidity-to-location map:",
+    "60 56 37",
+    "56 93 4",
+];
+
+const maps = ParseInput(tests);
+
+const demoSeed = FindObjectByID(14, maps.Seeds);
+
+Inspect(demoSeed);
+
+const demoSoil = FindObjectByID(demoSeed?.ID || 0, maps.SeedToSoil);
+
+Inspect(demoSoil);
+
+function ParseInput(almanac: string[]): RangeMaps {
+    /** An empty initializer for our output */
+    const output: RangeMaps = {
+        Seeds: [],
+        SeedToSoil: [],
+        SoilToFertilizer: [],
+        FertilizerToWater: [],
+        WaterToLight: [],
+        LightToTemperature: [],
+        TemperatureToHumidity: [],
+        HumidityToLocation: [],
+    };
+    /** A translation map for range titles to RangeMap keys*/
+
+
+    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: 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 {MappableObject[]} A list of mapped indices
+ */
+function ParseSourceDestinationRange(lineNumber: number, almanac: string[]): MappableObject[] {
+    const rangeMap: MappableObject[] = [];
+    do {
+        // Get the values out of the line
+        const [destinationRangeStart, sourceRangeStart, rangeLength] = ExtractNumbers(almanac[lineNumber]);
+        
+        // Create the ranges
+        for (let idx = 0; idx < rangeLength; idx++) {
+            rangeMap.push({
+                ID: sourceRangeStart + idx,
+                PointsTo: destinationRangeStart + idx,
+            });
+        }
+    } while(almanac[++lineNumber]);
+    
+    return rangeMap;
+}
+
+function FindObjectByID(needle: number, haystack: IdentifiableObject[]): IdentifiableObject|undefined {
+    return haystack.find((obj) => obj.ID == needle);
+}
+
+
+interface IdentifiableObject {
+    ID: number,
+};
+
+interface Seed extends IdentifiableObject {};
+
+interface MappableObject extends IdentifiableObject {
+    PointsTo: number,
+};
+
+type RangeMaps = {
+    Seeds: Seed[],
+    SeedToSoil: MappableObject[],
+    SoilToFertilizer: MappableObject[],
+    FertilizerToWater: MappableObject[],
+    WaterToLight: MappableObject[],
+    LightToTemperature: MappableObject[],
+    TemperatureToHumidity: MappableObject[],
+    HumidityToLocation: MappableObject[],
+}