123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- import { ExtractNumbers } from "../common.ts";
- export 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); });
-
- 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;
- }
- export function ParseSourceDestinationRange(lineNumber: number, almanac: string[]): RangeMap[] {
- const rangeMap: RangeMap[] = [];
- do {
-
- 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;
- }
- 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;
- }
- export function MapSeed(seedID: number, rangeMaps: RangeMaps): SeedMap|undefined {
-
- 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;
- }
- 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,
- };
- export type RangeMap = {
-
- SourceRanges: IDRange,
- DestinationRange: IDRange,
- };
- export type RangeMaps = {
-
- Seeds: number[],
-
- SeedToSoil: RangeMap[],
-
- SoilToFertilizer: RangeMap[],
-
- FertilizerToWater: RangeMap[],
-
- WaterToLight: RangeMap[],
-
- LightToTemperature: RangeMap[],
-
- TemperatureToHumidity: RangeMap[],
-
- HumidityToLocation: RangeMap[],
- }
- export type SeedMap = {
-
- ID: number,
-
- SoilID: number,
-
- FertilizerID: number,
-
- WaterID: number,
-
- LightID: number,
-
- TemperatureID: number,
-
- HumidityID: number,
-
- LocationID: number,
- }
|