105 lines
2.9 KiB
TypeScript
105 lines
2.9 KiB
TypeScript
|
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);
|