From 1afb266fa736b22eab5f7a1bd880d6a2fb6371e1 Mon Sep 17 00:00:00 2001 From: Seth Etter Date: Tue, 5 Dec 2023 20:40:59 -0600 Subject: [PATCH] part 2, attempt 1 -- brute force, no bueno --- 2023/day05/part2.ts | 68 +++++++++++++++++++++++++++++++++++++++++++-- 2023/day05/test.ts | 44 ++++++++++++++++++++++++++--- 2 files changed, 106 insertions(+), 6 deletions(-) diff --git a/2023/day05/part2.ts b/2023/day05/part2.ts index 5658bc9..b3c7bb9 100644 --- a/2023/day05/part2.ts +++ b/2023/day05/part2.ts @@ -1,3 +1,5 @@ +import { assert } from "https://deno.land/std@0.208.0/assert/mod.ts"; + if (import.meta.main) { const input = ( await Deno.readFile("input").then((bytes) => @@ -7,7 +9,69 @@ if (import.meta.main) { console.log(answer(input)); } +type Range = { + fromStart: number; + toStart: number; + range: number; +}; + +type MapRanges = { + from: string; + to: string; + ranges: Range[]; +}; + export function answer(input: string): number { - console.log(input); - return 42; + const [seedLine, _, ...mapLines] = input.split("\n"); + const seedRanges = seedLine + .replace("seeds: ", "") + .split(" ") + .map((x) => parseInt(x)); + + const seeds = []; + for (let i = 0; i < seedRanges.length; i += 2) { + const from = seedRanges[i]; + const to = from + seedRanges[i + 1]; + for (let j = 0; j < to - from; j++) { + seeds.push(seedRanges[i] + j); + } + } + + const mapRanges: MapRanges[] = mapLines + .join("\n") + .split("\n\n") + .map((mapLine) => { + const [fromToLine, ...rangeLines] = mapLine.split("\n"); + const [_, from, to] = fromToLine.match(/([a-z]+)-to-([a-z]+) map/)!; + const ranges = rangeLines.map((rangeLine) => { + const [toStart, fromStart, range] = rangeLine + .split(" ") + .map((n) => parseInt(n)); + return { fromStart, toStart, range }; + }); + + return { from, to, ranges }; + }); + + // start at `from: seed` to `to: location` + const locationNumbers = seeds.map((s) => getLocationNumber(s, mapRanges)); + + return Math.min(...locationNumbers); +} + +function getLocationNumber(seed: number, mapRanges: MapRanges[]): number { + let current = "seed"; + let currentNum = seed; + while (current !== "location") { + const mapRange = mapRanges.find(({ from }) => from === current); + assert(mapRange, `mapRange not found for: ${current}`); + + const range = mapRange.ranges.find( + (r) => currentNum >= r.fromStart && currentNum <= r.fromStart + r.range, + ); + if (range) currentNum = currentNum + (range.toStart - range.fromStart); + + current = mapRange.to; + } + return currentNum; } diff --git a/2023/day05/test.ts b/2023/day05/test.ts index cc26a92..f2962d3 100644 --- a/2023/day05/test.ts +++ b/2023/day05/test.ts @@ -10,6 +10,7 @@ Deno.test("part1", () => { "50 98 2", "52 50 48", "", + // 13 + (15-0) "soil-to-fertilizer map:", "0 15 37", "37 52 2", @@ -41,7 +42,42 @@ Deno.test("part1", () => { assertEquals(p1.answer(examples), 35); }); -// Deno.test("part2", () => { -// const examples = ["abc", "def"].join("\n"); -// assertEquals(p2.answer(examples), 42); -// }); +Deno.test("part2", () => { + const examples = [ + "seeds: 79 14 55 13", + "", + "seed-to-soil map:", + "50 98 2", + "52 50 48", + "", + // 13 + (15-0) + "soil-to-fertilizer map:", + "0 15 37", + "37 52 2", + "39 0 15", + "", + "fertilizer-to-water map:", + "49 53 8", + "0 11 42", + "42 0 7", + "57 7 4", + "", + "water-to-light map:", + "88 18 7", + "18 25 70", + "", + "light-to-temperature map:", + "45 77 23", + "81 45 19", + "68 64 13", + "", + "temperature-to-humidity map:", + "0 69 1", + "1 0 69", + "", + "humidity-to-location map:", + "60 56 37", + "56 93 4", + ].join("\n"); + assertEquals(p2.answer(examples), 46); +}); -- 2.51.2