aoc-2023/day_5/solve_2.ts
2024-12-09 22:41:02 +09:00

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);