Day 5
This commit is contained in:
@@ -33,5 +33,9 @@ defmodule Aoc2023.Common do
|
||||
|
||||
def id(x), do: x
|
||||
def const(_, x), do: x
|
||||
|
||||
def lines(x), do: String.split(x, "\n")
|
||||
|
||||
def head([head | _]), do: head
|
||||
def tail([_ | tail]), do: tail
|
||||
end
|
||||
|
||||
85
lib/day5.ex
Normal file
85
lib/day5.ex
Normal file
@@ -0,0 +1,85 @@
|
||||
defmodule Aoc2023.Day5 do
|
||||
use Aoc2023
|
||||
|
||||
defp numbers(str), do: str |> String.split() |> Enum.map(&String.to_integer/1)
|
||||
|
||||
def parse(input) do
|
||||
[seeds | maps] =
|
||||
input
|
||||
|> String.split("\n\n")
|
||||
|
||||
{
|
||||
seeds |> String.split(": ") |> Enum.at(1) |> numbers,
|
||||
maps
|
||||
|> Enum.map(pipe(
|
||||
String.split("\n")
|
||||
|> tail
|
||||
|> Enum.map(pipe(
|
||||
numbers
|
||||
|> List.to_tuple()
|
||||
|> then(fn {dst, src, len} -> {src .. (src + len - 1), dst - src} end)
|
||||
))
|
||||
))
|
||||
}
|
||||
end
|
||||
|
||||
defp split_range_on(r1, r2) do
|
||||
cond do
|
||||
Range.disjoint?(r1, r2) -> {[r1], []}
|
||||
r1.first < r2.first && r1.last < r2.last ->
|
||||
{a, b} = Range.split(r1, r2.first - r1.first)
|
||||
{[a], [b]}
|
||||
r1.first > r2.first && r1.last > r2.last ->
|
||||
{a, b} = Range.split(r1, r1.first - r2.first)
|
||||
{[b], [a]}
|
||||
r1.first >= r2.first && r1.last <= r2.last ->
|
||||
{[], [r1]}
|
||||
r1.first <= r2.first && r1.last >= r2.last
|
||||
or r1.first ->
|
||||
{pre, rest} = Range.split(r1, r2.first - r1.first)
|
||||
{mid, last} = Range.split(rest, r2.last - rest.first)
|
||||
{[pre, last], [mid]}
|
||||
end
|
||||
end
|
||||
|
||||
defp map(loc, map) do
|
||||
{unmapped, mapped} = for {src, offset} <- map,
|
||||
reduce: {[loc], []} do
|
||||
{unmapped, mapped} ->
|
||||
for range <- unmapped,
|
||||
reduce: {[], mapped} do
|
||||
{unmapped_, mapped_} ->
|
||||
{unmapped, mapped} = split_range_on(range, src)
|
||||
{
|
||||
unmapped_ ++ unmapped,
|
||||
mapped_ ++ Enum.map(mapped, &(Range.shift(&1, offset)))
|
||||
}
|
||||
end
|
||||
end
|
||||
unmapped ++ mapped
|
||||
end
|
||||
|
||||
defp run(seeds, maps) do
|
||||
for seed <- seeds do
|
||||
for map <- maps, reduce: [seed] do
|
||||
loc ->
|
||||
loc
|
||||
|> Enum.flat_map(pipe(map(map)))
|
||||
end
|
||||
end
|
||||
|> Enum.flat_map(&id/1)
|
||||
|> Enum.min_by(&(&1.first))
|
||||
|> then(&(&1.first))
|
||||
end
|
||||
|
||||
def part1({seeds, maps}) do
|
||||
run(seeds |> Enum.map(&(&1..&1)), maps)
|
||||
end
|
||||
|
||||
def part2({seeds, maps}) do
|
||||
run(
|
||||
seeds |> Enum.chunk_every(2) |> Enum.map(fn [s, len] -> s..(s + len - 1) end),
|
||||
maps
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -6,6 +6,7 @@ defmodule Mix.Tasks.Aoc do
|
||||
defp module(2), do: Aoc2023.Day2
|
||||
defp module(3), do: Aoc2023.Day3
|
||||
defp module(4), do: Aoc2023.Day4
|
||||
defp module(5), do: Aoc2023.Day5
|
||||
# [MODULE INSERTION POINT]
|
||||
|
||||
defp base_dir(), do: System.get_env("AOC_BASE")
|
||||
|
||||
33
tests/day5/1
Normal file
33
tests/day5/1
Normal file
@@ -0,0 +1,33 @@
|
||||
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
|
||||
1
tests/day5/1.1
Normal file
1
tests/day5/1.1
Normal file
@@ -0,0 +1 @@
|
||||
35
|
||||
1
tests/day5/1.2
Normal file
1
tests/day5/1.2
Normal file
@@ -0,0 +1 @@
|
||||
46
|
||||
Reference in New Issue
Block a user