diff --git a/2023/day05/deno.lock b/2023/day05/deno.lock new file mode 100644 index 0000000..2c1d001 --- /dev/null +++ b/2023/day05/deno.lock @@ -0,0 +1,37 @@ +{ + "version": "3", + "remote": { + "https://deno.land/std@0.208.0/assert/_constants.ts": "8a9da298c26750b28b326b297316cdde860bc237533b07e1337c021379e6b2a9", + "https://deno.land/std@0.208.0/assert/_diff.ts": "58e1461cc61d8eb1eacbf2a010932bf6a05b79344b02ca38095f9b805795dc48", + "https://deno.land/std@0.208.0/assert/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7", + "https://deno.land/std@0.208.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee", + "https://deno.land/std@0.208.0/assert/assert_almost_equals.ts": "e15ca1f34d0d5e0afae63b3f5d975cbd18335a132e42b0c747d282f62ad2cd6c", + "https://deno.land/std@0.208.0/assert/assert_array_includes.ts": "6856d7f2c3544bc6e62fb4646dfefa3d1df5ff14744d1bca19f0cbaf3b0d66c9", + "https://deno.land/std@0.208.0/assert/assert_equals.ts": "d8ec8a22447fbaf2fc9d7c3ed2e66790fdb74beae3e482855d75782218d68227", + "https://deno.land/std@0.208.0/assert/assert_exists.ts": "407cb6b9fb23a835cd8d5ad804e2e2edbbbf3870e322d53f79e1c7a512e2efd7", + "https://deno.land/std@0.208.0/assert/assert_false.ts": "0ccbcaae910f52c857192ff16ea08bda40fdc79de80846c206bfc061e8c851c6", + "https://deno.land/std@0.208.0/assert/assert_greater.ts": "ae2158a2d19313bf675bf7251d31c6dc52973edb12ac64ac8fc7064152af3e63", + "https://deno.land/std@0.208.0/assert/assert_greater_or_equal.ts": "1439da5ebbe20855446cac50097ac78b9742abe8e9a43e7de1ce1426d556e89c", + "https://deno.land/std@0.208.0/assert/assert_instance_of.ts": "3aedb3d8186e120812d2b3a5dea66a6e42bf8c57a8bd927645770bd21eea554c", + "https://deno.land/std@0.208.0/assert/assert_is_error.ts": "c21113094a51a296ffaf036767d616a78a2ae5f9f7bbd464cd0197476498b94b", + "https://deno.land/std@0.208.0/assert/assert_less.ts": "aec695db57db42ec3e2b62e97e1e93db0063f5a6ec133326cc290ff4b71b47e4", + "https://deno.land/std@0.208.0/assert/assert_less_or_equal.ts": "5fa8b6a3ffa20fd0a05032fe7257bf985d207b85685fdbcd23651b70f928c848", + "https://deno.land/std@0.208.0/assert/assert_match.ts": "c4083f80600bc190309903c95e397a7c9257ff8b5ae5c7ef91e834704e672e9b", + "https://deno.land/std@0.208.0/assert/assert_not_equals.ts": "9f1acab95bd1f5fc9a1b17b8027d894509a745d91bac1718fdab51dc76831754", + "https://deno.land/std@0.208.0/assert/assert_not_instance_of.ts": "0c14d3dfd9ab7a5276ed8ed0b18c703d79a3d106102077ec437bfe7ed912bd22", + "https://deno.land/std@0.208.0/assert/assert_not_match.ts": "3796a5b0c57a1ce6c1c57883dd4286be13a26f715ea662318ab43a8491a13ab0", + "https://deno.land/std@0.208.0/assert/assert_not_strict_equals.ts": "4cdef83df17488df555c8aac1f7f5ec2b84ad161b6d0645ccdbcc17654e80c99", + "https://deno.land/std@0.208.0/assert/assert_object_match.ts": "d8fc2867cfd92eeacf9cea621e10336b666de1874a6767b5ec48988838370b54", + "https://deno.land/std@0.208.0/assert/assert_rejects.ts": "45c59724de2701e3b1f67c391d6c71c392363635aad3f68a1b3408f9efca0057", + "https://deno.land/std@0.208.0/assert/assert_strict_equals.ts": "b1f538a7ea5f8348aeca261d4f9ca603127c665e0f2bbfeb91fa272787c87265", + "https://deno.land/std@0.208.0/assert/assert_string_includes.ts": "b821d39ebf5cb0200a348863c86d8c4c4b398e02012ce74ad15666fc4b631b0c", + "https://deno.land/std@0.208.0/assert/assert_throws.ts": "63784e951475cb7bdfd59878cd25a0931e18f6dc32a6077c454b2cd94f4f4bcd", + "https://deno.land/std@0.208.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56", + "https://deno.land/std@0.208.0/assert/equal.ts": "9f1a46d5993966d2596c44e5858eec821859b45f783a5ee2f7a695dfc12d8ece", + "https://deno.land/std@0.208.0/assert/fail.ts": "c36353d7ae6e1f7933d45f8ea51e358c8c4b67d7e7502028598fe1fea062e278", + "https://deno.land/std@0.208.0/assert/mod.ts": "37c49a26aae2b254bbe25723434dc28cd7532e444cf0b481a97c045d110ec085", + "https://deno.land/std@0.208.0/assert/unimplemented.ts": "d56fbeecb1f108331a380f72e3e010a1f161baa6956fd0f7cf3e095ae1a4c75a", + "https://deno.land/std@0.208.0/assert/unreachable.ts": "4600dc0baf7d9c15a7f7d234f00c23bca8f3eba8b140286aaca7aa998cf9a536", + "https://deno.land/std@0.208.0/fmt/colors.ts": "34b3f77432925eb72cf0bfb351616949746768620b8e5ead66da532f93d10ba2" + } +} diff --git a/2023/day05/part1.ts b/2023/day05/part1.ts index 5658bc9..d980fc2 100644 --- a/2023/day05/part1.ts +++ b/2023/day05/part1.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,60 @@ 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 seeds = seedLine + .replace("seeds: ", "") + .split(" ") + .map((x) => parseInt(x)); + + 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/puzzle.md b/2023/day05/puzzle.md index ff3420c..b4ff934 100644 --- a/2023/day05/puzzle.md +++ b/2023/day05/puzzle.md @@ -109,8 +109,31 @@ So, the lowest location number in this example is `*35*`. *What is the lowest location number that corresponds to any of the initial seed numbers?* -To begin, [get your puzzle input](5/input). +Your puzzle answer was `322500873`. + +The first half of this puzzle is complete! It provides one gold star: \* + +\--- Part Two --- +---------- + +Everyone will starve if you only plant such a small number of seeds. Re-reading the almanac, it looks like the `seeds:` line actually describes *ranges of seed numbers*. + +The values on the initial `seeds:` line come in pairs. Within each pair, the first value is the *start* of the range and the second value is the *length* of the range. So, in the first line of the example above: + +``` +seeds: 79 14 55 13 +``` + +This line describes two ranges of seed numbers to be planted in the garden. The first range starts with seed number `79` and contains `14` values: `79`, `80`, ..., `91`, `92`. The second range starts with seed number `55` and contains `13` values: `55`, `56`, ..., `66`, `67`. + +Now, rather than considering four seed numbers, you need to consider a total of *27* seed numbers. + +In the above example, the lowest location number can be obtained from seed number `82`, which corresponds to soil `84`, fertilizer `84`, water `84`, light `77`, temperature `45`, humidity `46`, and *location `46`*. So, the lowest location number is `*46*`. + +Consider all of the initial seed numbers listed in the ranges on the first line of the almanac. *What is the lowest location number that corresponds to any of the initial seed numbers?* Answer: -You can also [Shareon [Twitter](https://twitter.com/intent/tweet?text=%22If+You+Give+A+Seed+A+Fertilizer%22+%2D+Day+5+%2D+Advent+of+Code+2023&url=https%3A%2F%2Fadventofcode%2Ecom%2F2023%2Fday%2F5&related=ericwastl&hashtags=AdventOfCode) [Mastodon](javascript:void(0);)] this puzzle. \ No newline at end of file +Although it hasn't changed, you can still [get your puzzle input](5/input). + +You can also [Shareon [Twitter](https://twitter.com/intent/tweet?text=I%27ve+completed+Part+One+of+%22If+You+Give+A+Seed+A+Fertilizer%22+%2D+Day+5+%2D+Advent+of+Code+2023&url=https%3A%2F%2Fadventofcode%2Ecom%2F2023%2Fday%2F5&related=ericwastl&hashtags=AdventOfCode) [Mastodon](javascript:void(0);)] this puzzle. \ No newline at end of file diff --git a/2023/day05/test.ts b/2023/day05/test.ts index ef5e047..cc26a92 100644 --- a/2023/day05/test.ts +++ b/2023/day05/test.ts @@ -3,11 +3,45 @@ import * as p1 from "./part1.ts"; import * as p2 from "./part2.ts"; Deno.test("part1", () => { - const examples = ["abc", "def"].join("\n"); - assertEquals(p1.answer(examples), 42); + const examples = [ + "seeds: 79 14 55 13", + "", + "seed-to-soil map:", + "50 98 2", + "52 50 48", + "", + "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(p1.answer(examples), 35); }); -Deno.test("part2", () => { - const examples = ["abc", "def"].join("\n"); - assertEquals(p2.answer(examples), 42); -}); +// Deno.test("part2", () => { +// const examples = ["abc", "def"].join("\n"); +// assertEquals(p2.answer(examples), 42); +// });