blob: 8b8d063cbb024e2b0b8e5508401109231ebc6176 [file] [log] [blame]
import { readFileSync } from "fs";
const input = readFileSync('day 5/input.txt').toString().split('\n\n')
interface MappedRange {
startRange: [number, number];
offset: number;
}
interface Input {
sts: MappedRange[];
stf: MappedRange[];
ftw: MappedRange[];
wtl: MappedRange[];
ltt: MappedRange[];
tth: MappedRange[];
htl: MappedRange[];
}
function pointerMap(array: number[][]): MappedRange[] {
return array.map(arr => {
const startRange: [number, number] = [arr[1], arr[1] + arr[2]];
const offset = arr[0] - arr[1];
console.log(`Made descriptor (start -> dest): ${arr[1]} -> ${arr[0]} ... ${arr[1] + offset} -> ${arr[0] + offset}`)
return {
startRange,
offset
}
})
}
function findSmallestLocation(seeds: number[], mappedInput: Input): {
seed: number;
location: number;
} {
const locations: {seed: number, location: number}[] = [];
for(const seed of seeds) {
console.log(`Checking seed ${seed}`)
let s = mappedInput.sts.find(o => o.startRange[0] <= seed && seed <= o.startRange[1])
const soil = (s ? s.offset + seed : null) ?? seed
console.log(soil === seed ? `Continuing with default` : `Found ${soil}`)
let f = mappedInput.stf.find(o => o.startRange[0] <= soil && soil <= o.startRange[1])
const fertilizer = (f ? f.offset + soil : null) ?? soil
console.log(fertilizer === soil ? `Continuing with default` : `Found ${fertilizer}`)
let w = mappedInput.ftw.find(o => o.startRange[0] <= fertilizer && fertilizer <= o.startRange[1])
const water = (w ? w.offset + fertilizer : null) ?? fertilizer
console.log(water === fertilizer ? `Continuing with default` : `Found ${water}`)
let li = mappedInput.wtl.find(o => o.startRange[0] <= water && water <= o.startRange[1])
const light = (li ? li.offset + water : null) ?? water
console.log(light === water ? `Continuing with default` : `Found ${light}`)
let t = mappedInput.ltt.find(o => o.startRange[0] <= light && light <= o.startRange[1])
const temperature = (t ? t.offset + light : null) ?? light
console.log(temperature === light ? `Continuing with default` : `Found ${temperature}`)
let h = mappedInput.tth.find(o => o.startRange[0] <= temperature && temperature <= o.startRange[1])
const humidity = (h ? h.offset + temperature : null) ?? temperature
console.log(humidity === temperature ? `Continuing with default` : `Found ${humidity}`)
let lo = mappedInput.htl.find(o => o.startRange[0] <= humidity && humidity <= o.startRange[1])
const location = (lo ? lo.offset + humidity : null) ?? humidity
console.log(location === humidity ? `Continuing with default` : `Found ${location}`)
locations.push({seed, location})
}
const sorted = locations.sort((a,b) => a.location < b.location ? -1 : 1);
return sorted[0]
}
const mappedInput: Input = {
sts: pointerMap(input[1].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)))),
stf: pointerMap(input[2].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)))),
ftw: pointerMap(input[3].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)))),
wtl: pointerMap(input[4].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)))),
ltt: pointerMap(input[5].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)))),
tth: pointerMap(input[6].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)))),
htl: pointerMap(input[7].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n))))
};
console.log(`Generating descriptors for seed to soil`);
console.log(`Generating descriptors for soil to fertilizer`);
console.log(`Generating descriptors for fertilizer to water`);
console.log(`Generating descriptors for water to light`);
console.log(`Generating descriptors for light to temp`);
console.log(`Generating descriptors for temp to humidity`);
console.log(`Generating descriptors for humidity to location`);
// Part 1
;(() => {
const seeds = input[0].split(':')[1].trim().split(' ').map(i => parseInt(i));
const smallest = findSmallestLocation(seeds, mappedInput)
console.log(`(Part 1) Lowest location number: (seed: ${smallest.seed}) ${smallest.location}`)
})();
// Part 2
function findSmallestLocationRange(seeds: number[], mappedInput: Input): {
seed: number;
location: number;
} {
const locations: {seed: number, location: number}[] = [];
for(const seed of seeds) {
console.log(`Checking seed ${seed}`)
let s = mappedInput.sts.find(o => o.startRange[0] <= seed && seed <= o.startRange[1])
const soil = (s ? s.offset + seed : null) ?? seed
console.log(soil === seed ? `Continuing with default` : `Found ${soil}`)
let f = mappedInput.stf.find(o => o.startRange[0] <= soil && soil <= o.startRange[1])
const fertilizer = (f ? f.offset + soil : null) ?? soil
console.log(fertilizer === soil ? `Continuing with default` : `Found ${fertilizer}`)
let w = mappedInput.ftw.find(o => o.startRange[0] <= fertilizer && fertilizer <= o.startRange[1])
const water = (w ? w.offset + fertilizer : null) ?? fertilizer
console.log(water === fertilizer ? `Continuing with default` : `Found ${water}`)
let li = mappedInput.wtl.find(o => o.startRange[0] <= water && water <= o.startRange[1])
const light = (li ? li.offset + water : null) ?? water
console.log(light === water ? `Continuing with default` : `Found ${light}`)
let t = mappedInput.ltt.find(o => o.startRange[0] <= light && light <= o.startRange[1])
const temperature = (t ? t.offset + light : null) ?? light
console.log(temperature === light ? `Continuing with default` : `Found ${temperature}`)
let h = mappedInput.tth.find(o => o.startRange[0] <= temperature && temperature <= o.startRange[1])
const humidity = (h ? h.offset + temperature : null) ?? temperature
console.log(humidity === temperature ? `Continuing with default` : `Found ${humidity}`)
let lo = mappedInput.htl.find(o => o.startRange[0] <= humidity && humidity <= o.startRange[1])
const location = (lo ? lo.offset + humidity : null) ?? humidity
console.log(location === humidity ? `Continuing with default` : `Found ${location}`)
locations.push({seed, location})
}
const sorted = locations.sort((a,b) => a.location < b.location ? -1 : 1);
return sorted[0]
}
;(() => {
const unformattedSeeds = input[0].split(':')[1].trim().match(/(\d+ \d+)/g)?.map(i => i.split(' ').map(n => parseInt(n.trim())))
const seeds: number[] = [];
if(!unformattedSeeds) throw new Error('How did this happen')
for(const US of unformattedSeeds) {
for(let i = 0; i < US[1]; i++) {
seeds.push(US[0] + i);
}
}
const smallest = findSmallestLocation(seeds, mappedInput)
console.log(`(Part 2) Lowest location number: (seed: ${smallest.seed}) ${smallest.location}`)
})();