adventofcode2023/day5/main.ts

183 lines
4.6 KiB
TypeScript

// title: game title
// author: game developer
// desc: short description
// script: js
/// <reference path="./input.ts"/>
// Maps are [dest source range]
const input = fullInput;
let seeds = input[0].split(" ").map((o) => Number(o));
seeds.shift();
const seedsPairs: [number, number][] = [];
for (let i = 0; i < seeds.length; i += 2) {
seedsPairs.push([seeds[i], seeds[i + 1]]);
}
trace(JSON.stringify(seedsPairs));
let seedToSoil: number[][] = [];
let soilToFertilizer: number[][] = [];
let fertilizerToWater: number[][] = [];
let waterToLight: number[][] = [];
let lightToTemp: number[][] = [];
let tempToHumidity: number[][] = [];
let humidityToLocation: number[][] = [];
let curr = seedToSoil;
// Roughly save input values
for (const line of input) {
if (line === "seed-to-soil map:") {
curr = seedToSoil;
}
if (line === "soil-to-fertilizer map:") {
curr = soilToFertilizer;
}
if (line === "fertilizer-to-water map:") {
curr = fertilizerToWater;
}
if (line === "water-to-light map:") {
curr = waterToLight;
}
if (line === "light-to-temperature map:") {
curr = lightToTemp;
}
if (line === "temperature-to-humidity map:") {
curr = tempToHumidity;
}
if (line === "humidity-to-location map:") {
curr = humidityToLocation;
}
curr.push(line.split(" ").map((o) => Number(o)));
}
// Clean and sort the maps
for (const map of [
seedToSoil,
soilToFertilizer,
fertilizerToWater,
waterToLight,
lightToTemp,
tempToHumidity,
humidityToLocation,
]) {
map.shift();
}
function cleanInput(o: number[]): boolean {
return o.length === 3;
}
seedToSoil = seedToSoil.filter(cleanInput);
soilToFertilizer = soilToFertilizer.filter(cleanInput);
fertilizerToWater = fertilizerToWater.filter(cleanInput);
waterToLight = waterToLight.filter(cleanInput);
lightToTemp = lightToTemp.filter(cleanInput);
tempToHumidity = tempToHumidity.filter(cleanInput);
humidityToLocation = humidityToLocation.filter(cleanInput);
/**
* Given a source input and a list of maps, calculate the destination value
* @param source
* @param maps in the form of [[dest, sourceFrom, sourceTo]]
* @returns
*/
function sourceToDestination(source: number, maps: number[][]): number {
let dest = -1;
// Iterate the maps and find the one that matches the source
for (const map of maps) {
const sourceFrom = map[1];
const sourceTo = map[1] + map[2] - 1;
if (source >= sourceFrom && source <= sourceTo) {
dest = map[0] + source - sourceFrom;
}
}
if (dest > -1) return dest;
return source;
}
let minimalLocation = Number.MAX_VALUE;
for (const pair of seedsPairs) {
trace(JSON.stringify(pair));
const to = pair[0] + pair[1] - 1;
for (let seed = pair[0]; seed < to; seed++) {
const soil = sourceToDestination(seed, seedToSoil);
const fert = sourceToDestination(soil, soilToFertilizer);
const water = sourceToDestination(fert, fertilizerToWater);
const light = sourceToDestination(water, waterToLight);
const temp = sourceToDestination(light, lightToTemp);
const hum = sourceToDestination(temp, tempToHumidity);
const loc = sourceToDestination(hum, humidityToLocation);
if (loc < minimalLocation) minimalLocation = loc;
}
}
trace(minimalLocation);
// VISUALIZATION
trace("VISUALIZATION");
const steps = [
{ name: "Seeds", map: seedToSoil },
{ name: "Soil", map: soilToFertilizer },
{ name: "Fertilizer", map: fertilizerToWater },
{ name: "Water", map: waterToLight },
{ name: "Light", map: lightToTemp },
{ name: "Temperature", map: tempToHumidity },
{ name: "Humidity", map: humidityToLocation },
{ name: "Location", map: [[0, 0, 0]] },
];
const seed = {
index: 0,
step: 0,
value: seeds[0],
};
const x = 100;
const speed = 10;
let frames = 1;
cls();
function TIC() {
++frames;
const offset = 15;
const lineLen = 100;
let y = 1;
if (frames % speed === 0) {
seed.value = sourceToDestination(seed.value, steps[seed.step].map);
++seed.step;
if (seed.step >= steps.length) {
seed.step = 0;
if (++seed.index >= seeds.length) {
seed.index = 0;
}
seed.value = seeds[seed.index];
}
for (let x = 0; x < 240; ++x) {
for (let y = 0; y < 136; ++y) {
const c = pix(x, y);
if (c >= 12) {
pix(x, y, c + 1);
}
}
}
}
rect(200, 0, 50, 136, 0);
for (const [i, step] of steps.entries()) {
print(step.name, 1, y, i + 2);
line(100, y + 2, x + lineLen, y + 2, i + 2);
y += offset;
}
const yOffset = ((frames % speed) / speed) * 12;
circ(seed.value + x, seed.step * offset + 2 + yOffset, 2, 12);
print(seed.value, x + lineLen + 5, seed.step * offset + yOffset, 12);
}