|
@@ -42,7 +42,7 @@ const input = await LoadInput(5);
|
|
|
const maps = ParseInput(input);
|
|
|
|
|
|
|
|
|
-const seeds = maps.Seeds.map((seed) => MapSeed(seed.ID, maps));
|
|
|
+const seeds = maps.Seeds.map((seed) => MapSeed(seed, maps));
|
|
|
|
|
|
|
|
|
let closestLocationID = Number.MAX_SAFE_INTEGER;
|
|
@@ -75,7 +75,7 @@ function ParseInput(almanac: string[]): RangeMaps {
|
|
|
|
|
|
const seedIDs = ExtractNumbers(line);
|
|
|
|
|
|
- seedIDs.forEach((id) => { output.Seeds.push({ID: id}); });
|
|
|
+ seedIDs.forEach((id) => { output.Seeds.push(id); });
|
|
|
|
|
|
i++;
|
|
|
}
|
|
@@ -117,35 +117,46 @@ function ParseInput(almanac: string[]): RangeMaps {
|
|
|
*
|
|
|
* @param {number} lineNumber The line number to begin parsing from
|
|
|
* @param {string[]} almanac The complete almanac
|
|
|
- * @returns {MappableObject[]} A list of mapped indices
|
|
|
+ * @returns {RangeMap[]} A list of mapped indices
|
|
|
*/
|
|
|
-function ParseSourceDestinationRange(lineNumber: number, almanac: string[]): MappableObject[] {
|
|
|
- const rangeMap: MappableObject[] = [];
|
|
|
+function ParseSourceDestinationRange(lineNumber: number, almanac: string[]): RangeMap[] {
|
|
|
+ const rangeMap: RangeMap[] = [];
|
|
|
do {
|
|
|
|
|
|
const [destinationRangeStart, sourceRangeStart, rangeLength] = ExtractNumbers(almanac[lineNumber]);
|
|
|
|
|
|
-
|
|
|
- for (let idx = 0; idx < rangeLength; idx++) {
|
|
|
- rangeMap.push({
|
|
|
- ID: sourceRangeStart + idx,
|
|
|
- PointsTo: destinationRangeStart + idx,
|
|
|
- });
|
|
|
- }
|
|
|
+ rangeMap.push({
|
|
|
+ SourceRanges: {
|
|
|
+ Start: sourceRangeStart,
|
|
|
+ End: sourceRangeStart + rangeLength - 1,
|
|
|
+ },
|
|
|
+ DestinationRange: {
|
|
|
+ Start: destinationRangeStart,
|
|
|
+ End: destinationRangeStart + rangeLength - 1,
|
|
|
+ }
|
|
|
+ });
|
|
|
} while(almanac[++lineNumber]);
|
|
|
|
|
|
return rangeMap;
|
|
|
}
|
|
|
|
|
|
|
|
|
- * Find an IdentifiableObject by its ID number
|
|
|
+ * 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 needle The ID number to find
|
|
|
- * @param haystack The list to find the ID in
|
|
|
- * @returns {IdentifiableObject|undefined} The object by that ID if found, or undefined
|
|
|
+ * @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 FindObjectByID(needle: number, haystack: IdentifiableObject[]|MappableObject[]): IdentifiableObject|MappableObject|undefined {
|
|
|
- return haystack.find((obj) => obj.ID == needle);
|
|
|
+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;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -160,7 +171,7 @@ function FindObjectByID(needle: number, haystack: IdentifiableObject[]|MappableO
|
|
|
*/
|
|
|
function MapSeed(seedID: number, rangeMaps: RangeMaps): SeedMap|undefined {
|
|
|
|
|
|
- if(!FindObjectByID(seedID, rangeMaps.Seeds)) { return undefined; }
|
|
|
+ if(!rangeMaps.Seeds.includes(seedID)) { return undefined; }
|
|
|
|
|
|
|
|
|
const seed: SeedMap = {
|
|
@@ -174,13 +185,13 @@ function MapSeed(seedID: number, rangeMaps: RangeMaps): SeedMap|undefined {
|
|
|
LocationID: 0,
|
|
|
};
|
|
|
|
|
|
- seed.SoilID = (FindObjectByID(seedID, rangeMaps.SeedToSoil) as MappableObject)?.PointsTo || seedID;
|
|
|
- seed.FertilizerID = (FindObjectByID(seed.SoilID, rangeMaps.SoilToFertilizer) as MappableObject)?.PointsTo || seed.SoilID;
|
|
|
- seed.WaterID = (FindObjectByID(seed.FertilizerID, rangeMaps.FertilizerToWater) as MappableObject)?.PointsTo || seed.FertilizerID;
|
|
|
- seed.LightID = (FindObjectByID(seed.WaterID, rangeMaps.WaterToLight) as MappableObject)?.PointsTo || seed.WaterID;
|
|
|
- seed.TemperatureID = (FindObjectByID(seed.LightID, rangeMaps.LightToTemperature) as MappableObject)?.PointsTo|| seed.LightID;
|
|
|
- seed.HumidityID = (FindObjectByID(seed.TemperatureID, rangeMaps.TemperatureToHumidity) as MappableObject)?.PointsTo || seed.TemperatureID;
|
|
|
- seed.LocationID = (FindObjectByID(seed.HumidityID, rangeMaps.HumidityToLocation) as MappableObject)?.PointsTo || seed.HumidityID;
|
|
|
+ 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;
|
|
|
}
|
|
@@ -206,39 +217,36 @@ function isSeedMapArray(valueArray: any[]): valueArray is SeedMap[] {
|
|
|
&& Object.hasOwn(value, "LocationID");
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-interface IdentifiableObject {
|
|
|
-
|
|
|
- ID: number,
|
|
|
+type IDRange = {
|
|
|
+ Start: number,
|
|
|
+ End: number,
|
|
|
};
|
|
|
|
|
|
-
|
|
|
-interface Seed extends IdentifiableObject {};
|
|
|
-
|
|
|
|
|
|
-interface MappableObject extends IdentifiableObject {
|
|
|
+type RangeMap = {
|
|
|
|
|
|
- PointsTo: number,
|
|
|
+ SourceRanges: IDRange,
|
|
|
+ DestinationRange: IDRange,
|
|
|
};
|
|
|
|
|
|
|
|
|
type RangeMaps = {
|
|
|
|
|
|
- Seeds: Seed[],
|
|
|
+ Seeds: number[],
|
|
|
|
|
|
- SeedToSoil: MappableObject[],
|
|
|
+ SeedToSoil: RangeMap[],
|
|
|
|
|
|
- SoilToFertilizer: MappableObject[],
|
|
|
+ SoilToFertilizer: RangeMap[],
|
|
|
|
|
|
- FertilizerToWater: MappableObject[],
|
|
|
+ FertilizerToWater: RangeMap[],
|
|
|
|
|
|
- WaterToLight: MappableObject[],
|
|
|
+ WaterToLight: RangeMap[],
|
|
|
|
|
|
- LightToTemperature: MappableObject[],
|
|
|
+ LightToTemperature: RangeMap[],
|
|
|
|
|
|
- TemperatureToHumidity: MappableObject[],
|
|
|
+ TemperatureToHumidity: RangeMap[],
|
|
|
|
|
|
- HumidityToLocation: MappableObject[],
|
|
|
+ HumidityToLocation: RangeMap[],
|
|
|
}
|
|
|
|
|
|
|