import { InputType } from "./parser.ts"; import { parseInput, MapType } from "./parser.ts"; type Range = { start: number, // inclusive length: number, // exclusive } function getIntersection(r1: Range, r2: Range): Range | null { if (r1.start + r1.length <= r2.start) { return null; } if (r2.start + r2.length <= r1.start) { return null; } return { start: Math.max(r1.start, r2.start), length: Math.min(r1.start + r1.length, r2.start + r2.length) - Math.max(r1.start, r2.start) }; } function mappingRange(m: MapType, input: Range): Range[] { const result: Range[] = []; //collect all unmapped range const unmappedRange: Range[] = []; let curPos = 0; for (let i = 0; i < m.data.length; i++) { // data is sorted by src const d = m.data[i]; if (curPos < d.src) { unmappedRange.push({ start: curPos, length: d.src - curPos }); } curPos = d.src + d.range; } unmappedRange.push({ start: curPos, length: Infinity }); // collect all intersecting range for (let i = 0; i < m.data.length; i++) { const d = m.data[i]; const intersection = getIntersection(input, { start: d.src, length: d.range }) if (intersection === null) { continue; } // mapping result.push({ start: d.dst + intersection.start - d.src, length: intersection.length }); } // add unmapped range for (let i = 0; i < unmappedRange.length; i++) { const intersection = getIntersection(input, unmappedRange[i]); if (intersection === null) { continue; } result.push(intersection); } // console.log("mapType", m) // console.log("input", input) // console.log("unmapped", unmappedRange) // console.log("result",result) return result; } const input = await Deno.readTextFile("input.txt"); const r = parseInput(input); function composition(r: InputType, input: Range) { let result = [input]; for (let i = 0; i < r.map.length; i++) { const m = r.map[i]; result = result.flatMap(r => mappingRange(m, r)); } return result // ["soil", "fertilizer", "water", "light", "temperature", "humidity", "location"].forEach((key) => { // const m = r.map.filter(m => m.to === key)[0]; // }); } let min = Infinity; for (let i = 0; i < r.seeds.length; i += 2) { const seed = r.seeds[i]; const seedLength = r.seeds[i + 1]; const seedRange = { start: seed, length: seedLength }; const location = composition(r, seedRange); console.log("location", location); const minStart = location.reduce((a, b) => Math.min(a, b.start), Infinity); min = Math.min(min, minStart); } console.log(min);