|
@@ -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 {
|
|
|
+
|
|
|
+ const output: RangeMaps = {
|
|
|
+ Seeds: [],
|
|
|
+ SeedToSoil: [],
|
|
|
+ SoilToFertilizer: [],
|
|
|
+ FertilizerToWater: [],
|
|
|
+ WaterToLight: [],
|
|
|
+ LightToTemperature: [],
|
|
|
+ TemperatureToHumidity: [],
|
|
|
+ HumidityToLocation: [],
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ for (let i = 0; i < almanac.length; i++) {
|
|
|
+ let line = almanac[i];
|
|
|
+
|
|
|
+
|
|
|
+ if (/^seeds:/.test(line)) {
|
|
|
+
|
|
|
+ const seedIDs = ExtractNumbers(line);
|
|
|
+
|
|
|
+ seedIDs.forEach((id) => { output.Seeds.push({ID: id}); });
|
|
|
+
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+
|
|
|
+ else if (/^seed\-to/.test(line)) {
|
|
|
+ output.SeedToSoil = ParseSourceDestinationRange(++i, almanac);
|
|
|
+ }
|
|
|
+
|
|
|
+ else if (/^soil\-to/.test(line)) {
|
|
|
+ output.SoilToFertilizer = ParseSourceDestinationRange(++i, almanac);
|
|
|
+ }
|
|
|
+
|
|
|
+ else if (/^fertilizer\-to/.test(line)) {
|
|
|
+ output.FertilizerToWater = ParseSourceDestinationRange(++i, almanac);
|
|
|
+ }
|
|
|
+
|
|
|
+ else if (/^water\-to/.test(line)) {
|
|
|
+ output.WaterToLight = ParseSourceDestinationRange(++i, almanac);
|
|
|
+ }
|
|
|
+
|
|
|
+ else if (/^light\-to/.test(line)) {
|
|
|
+ output.LightToTemperature = ParseSourceDestinationRange(++i, almanac);
|
|
|
+ }
|
|
|
+
|
|
|
+ else if (/^temperature\-to/.test(line)) {
|
|
|
+ output.TemperatureToHumidity = ParseSourceDestinationRange(++i, almanac);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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 {
|
|
|
+
|
|
|
+ const [destinationRangeStart, sourceRangeStart, rangeLength] = ExtractNumbers(almanac[lineNumber]);
|
|
|
+
|
|
|
+
|
|
|
+ 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[],
|
|
|
+}
|