166 lines
4.1 KiB
TypeScript
166 lines
4.1 KiB
TypeScript
const sample = await Deno.readTextFile("sample.txt");
|
|
const input = await Deno.readTextFile("input.txt");
|
|
|
|
interface Map {
|
|
s: number;
|
|
d: number;
|
|
l: number;
|
|
}
|
|
|
|
interface ParsedInput {
|
|
seeds: number[];
|
|
seedToSoil: Map[];
|
|
soilToFertilizer: Map[];
|
|
fertilizerToWater: Map[];
|
|
waterToLight: Map[];
|
|
lightToTemperature: Map[];
|
|
temperatureToHumidity: Map[];
|
|
humidityToLocation: Map[];
|
|
}
|
|
|
|
const computeMap = (maps: Map[]) => (input: number): number => {
|
|
for (const { s, d, l } of maps) {
|
|
if (input >= s && input < s + l) return (input - s) + d;
|
|
}
|
|
return input;
|
|
};
|
|
|
|
const parseInput = (input: string): ParsedInput => {
|
|
const seeds: number[] =
|
|
input.split("\n\n").shift()?.split(" ").slice(1).map(parseFloat) || [];
|
|
|
|
const parsed = input.split("\n\n")
|
|
.filter(Boolean)
|
|
.slice(1)
|
|
.map((map): string[] => map.split(/:\ |\ map:\ *\n*/))
|
|
.map((
|
|
[name, rows],
|
|
): [string, number[][]] => [
|
|
name,
|
|
rows.trim().split(/\n/).map((values) =>
|
|
values.split(/\ /).map(parseFloat)
|
|
),
|
|
]);
|
|
|
|
let seedToSoil: Map[] = [];
|
|
let soilToFertilizer: Map[] = [];
|
|
let fertilizerToWater: Map[] = [];
|
|
let waterToLight: Map[] = [];
|
|
let lightToTemperature: Map[] = [];
|
|
let temperatureToHumidity: Map[] = [];
|
|
let humidityToLocation: Map[] = [];
|
|
|
|
parsed.forEach((
|
|
[name, mapValues],
|
|
) => {
|
|
const maps = mapValues.map(([d, s, l]) => ({ d, s, l }));
|
|
if (name === "seed-to-soil") {
|
|
seedToSoil = maps;
|
|
} else if (name === "soil-to-fertilizer") {
|
|
soilToFertilizer = maps;
|
|
} else if (name === "fertilizer-to-water") {
|
|
fertilizerToWater = maps;
|
|
} else if (name === "water-to-light") {
|
|
waterToLight = maps;
|
|
} else if (name === "light-to-temperature") {
|
|
lightToTemperature = maps;
|
|
} else if (name === "temperature-to-humidity") {
|
|
temperatureToHumidity = maps;
|
|
} else if (name === "humidity-to-location") {
|
|
humidityToLocation = maps;
|
|
}
|
|
});
|
|
|
|
return {
|
|
seeds,
|
|
seedToSoil,
|
|
soilToFertilizer,
|
|
fertilizerToWater,
|
|
waterToLight,
|
|
lightToTemperature,
|
|
temperatureToHumidity,
|
|
humidityToLocation,
|
|
};
|
|
};
|
|
|
|
const solvePart1 = (data: string): number => {
|
|
const {
|
|
seeds,
|
|
seedToSoil,
|
|
soilToFertilizer,
|
|
fertilizerToWater,
|
|
waterToLight,
|
|
lightToTemperature,
|
|
temperatureToHumidity,
|
|
humidityToLocation,
|
|
} = parseInput(data);
|
|
|
|
return seeds
|
|
.map(computeMap(seedToSoil))
|
|
.map(computeMap(soilToFertilizer))
|
|
.map(computeMap(fertilizerToWater))
|
|
.map(computeMap(waterToLight))
|
|
.map(computeMap(lightToTemperature))
|
|
.map(computeMap(temperatureToHumidity))
|
|
.map(computeMap(humidityToLocation))
|
|
.reduce((m, v) => Math.min(m, v));
|
|
};
|
|
|
|
console.log("Sample:", solvePart1(sample)); // 35
|
|
console.log("Input", solvePart1(input)); // 265018614
|
|
|
|
const getRanges = (list: number[]): [number, number][] => {
|
|
const result: [number, number][] = [];
|
|
for (let i = 0; i < list.length; i += 2) {
|
|
result.push([list[i], list[i + 1]]);
|
|
}
|
|
return result;
|
|
};
|
|
|
|
const mapRange = (s: number, l: number, fn: (n: number) => void): void => {
|
|
for (let i = s; i < s + l; i += 1) {
|
|
fn(i);
|
|
}
|
|
};
|
|
|
|
const solvePart2 = (data: string): number => {
|
|
const {
|
|
seeds: seedRanges,
|
|
seedToSoil,
|
|
soilToFertilizer,
|
|
fertilizerToWater,
|
|
waterToLight,
|
|
lightToTemperature,
|
|
temperatureToHumidity,
|
|
humidityToLocation,
|
|
} = parseInput(data);
|
|
|
|
console.log("getRanges(seedRanges)", getRanges(seedRanges));
|
|
|
|
const fn = (n: number): number =>
|
|
computeMap(humidityToLocation)(
|
|
computeMap(temperatureToHumidity)(
|
|
computeMap(lightToTemperature)(
|
|
computeMap(waterToLight)(
|
|
computeMap(fertilizerToWater)(
|
|
computeMap(soilToFertilizer)(computeMap(seedToSoil)(n)),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
let lowest = Number.MAX_VALUE
|
|
getRanges(seedRanges).forEach(([s, l]) => {
|
|
console.log("range", s, lowest);
|
|
mapRange(s, l, (n) => {
|
|
lowest = Math.min(lowest, fn(n));
|
|
});
|
|
});
|
|
|
|
return lowest;
|
|
};
|
|
|
|
console.log("Sample:", solvePart2(sample)); // 46
|
|
console.log("Input", solvePart2(input)); // 63179500
|