From a275ba28c8f05afd642dc0194d4e87289a534311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Kn=C3=B6pfle?= Date: Mon, 19 Dec 2022 22:38:16 +0100 Subject: [PATCH 1/2] wip --- lib/aoc2022/door12.ex | 101 +++++++++++++++++++++++++++++++++++ script/12/input.txt | 41 ++++++++++++++ test/aoc2022/door12_test.exs | 46 ++++++++++++++++ 3 files changed, 188 insertions(+) create mode 100644 lib/aoc2022/door12.ex create mode 100644 script/12/input.txt create mode 100644 test/aoc2022/door12_test.exs diff --git a/lib/aoc2022/door12.ex b/lib/aoc2022/door12.ex new file mode 100644 index 0000000..bb269a5 --- /dev/null +++ b/lib/aoc2022/door12.ex @@ -0,0 +1,101 @@ +defmodule Aoc2022.Door12 do + use Aoc2022.DoorBehaviour + + def run_a(stream) do + stream + |> Stream.map(&String.trim/1) + |> Stream.map(&String.to_charlist/1) + |> Stream.with_index() + |> Enum.reduce({%{}, nil}, fn {row, index}, {heightmap, goal} -> + row + |> Enum.with_index() + |> Enum.reduce({heightmap, goal}, &convert_row(index, &1, &2)) + end) + |> find_shortest_path() + end + + @start ?a - 1 + @goal ?z + 1 + defp convert_row(y, {?S, x}, {map, goal}), + do: {Map.put(map, {x, y}, {@start, 0, nil}), goal} + + defp convert_row(y, {?E, x}, {map, _}), + do: {Map.put(map, {x, y}, {@goal, :infinity, nil}), {x, y}} + + defp convert_row(y, {height, x}, {map, goal}), + do: {Map.put(map, {x, y}, {height, :infinity, nil}), goal} + + defp find_shortest_path({heightmap, goal}) do + find_shortest_path(heightmap, MapSet.new(Map.keys(heightmap)), goal) + end + + defp find_shortest_path(heightmap, remaining, goal) do + {{x, y} = min, {level, distance, _}} = + heightmap + |> Map.take(remaining |> MapSet.to_list()) + |> Enum.min_by(fn {_, {_, value, _}} -> value end) + + if min == goal do + heightmap + |> print_debug(goal) + |> Map.get(goal) + |> elem(1) + else + remaining = MapSet.delete(remaining, min) + + heightmap + |> Map.take([{x - 1, y}, {x, y - 1}, {x + 1, y}, {x, y + 1}]) + |> Enum.filter(fn {key, {other, _, _}} -> + level + 1 >= other and MapSet.member?(remaining, key) + end) + |> Enum.reduce(heightmap, fn {key, {height, other_distance, _}}, map -> + new_distance = distance + 1 + + if new_distance < other_distance do + Map.put(map, key, {height, new_distance, min}) + else + map + end + end) + |> find_shortest_path(remaining, goal) + end + end + + defp print_debug(heightmap, goal) do + max_x = heightmap |> Map.keys() |> Enum.map(&elem(&1, 0)) |> Enum.max() + max_y = heightmap |> Map.keys() |> Enum.map(&elem(&1, 1)) |> Enum.max() + path = build_path(heightmap, [goal]) + sparse = Map.take(heightmap, path) + + for y <- 0..max_y do + for x <- 0..max_x do + Map.get(sparse, {x, y}) + |> case do + nil -> "." + {_, _, nil} -> "S" + {_, _, {a, b}} when a + 1 == x and b == y -> ">" + {_, _, {a, b}} when a - 1 == x and b == y -> "<" + {_, _, {a, b}} when a == x and b - 1 == y -> "^" + {_, _, {a, b}} when a == x and b + 1 == y -> "v" + end + |> IO.write() + end + + IO.write("\n") + end + + heightmap + end + + def build_path(_, [nil | route]) do + route + end + + def build_path(heightmap, [last | _] = all) do + {_, _, next} = Map.get(heightmap, last) + build_path(heightmap, [next | all]) + end + + def run_b(_stream) do + end +end diff --git a/script/12/input.txt b/script/12/input.txt new file mode 100644 index 0000000..45dff51 --- /dev/null +++ b/script/12/input.txt @@ -0,0 +1,41 @@ +abcccaaaaacccacccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaacaccccccaaacccccccccccccccccccccccccccccccccccaaaaaaaaccccccccccccccccccccccccccccccccaaaaaa +abcccaaaaacccaaacaaacccccccccccccccccaaccccccacccaacccccccccccaacccccaaaaaaaaaaaccaaaaaaccccccccccccccccccccccccccccccccccaaaaaccccccccccccccccccccccccccccccccccaaaaaa +abccccaaaaaccaaaaaaaccccccccccccccaaaacccccccaacaaacccccccccaaaaaacccaaaaaaaaaaaccaaaaaacccccccccccccccccccccccccccccccccccaaaaaccccccccccccccaaacccccccccccccccccaaaaa +abccccaacccccaaaaaacccccccccccccccaaaaaacccccaaaaaccccccccccaaaaaacaaaaaaaaaaaaaccaaaaaacccccccccccccccccccccccccccccccccccaacaaccccccccccccccaaaaccccccccccccccccccaaa +abccccccccccaaaaaaaacccccccccccaaccaaaaaccccccaaaaaacccccccccaaaaacaaaaaaaaccccccccaaaaacccccccccccccccccccccccccccccccccccaacccccccccccccccccaaaaccaaacccccccccccccaac +abaaaaaccccaaaaaaaaaaccccccaaccaacaaaaacccccaaaaaaaaaaacccccaaaaacaaaacaaaaacccccccaacaacccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaaaaacccccccccccaaac +abaaaaaccccaaaaaaaaaacaacccaaaaaacaccaacccccaaaaaaaaaaacccccaaaaaccccccaaaaaccccccccccaacccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaakkkllccccccccccccccc +abaaaaacccccccaaacaaaaaaccccaaaaaaaccccccaaacccaacccaaaaaaacccccccccccccaaaaacccccccccaaaaaaccccccccccccccccccccccccccaaccccccccccccccccccccccackkkkkklllccccaaaccccccc +abaaaaacccccccaaacaaaaaaacccaaaaaaaccccccaaaacaaacaaaaaaaacccccccccccccaaaaaacccccccccaaaaaaccaacaacccccccccccccccaaaaaacccccccccccccccccccaaakkkkkkkkllllcccaaacaccccc +abaaaaaccccccccaacaaaaaaaacaaaaaaccccccccaaaaaaacaaaaaaaaacccccccccccccaaaacccccccccaaaaaaacccaaaaacccccccccccccccaaaaaaccccccccccccccccjjjjjkkkkkkpppplllcccaaaaaacccc +abaaaccccccccccccccaaaaaaacaaaaaacccccccccaaaaaaccaaaaaaaccccccccccccccccaaaccccccccaaaaaaaccccaaaaacccccccccccccccaaaaaaaccccaaccccccjjjjjjjkkkkppppppplllcccaaaaacccc +abccccccccccccccccaaaaaacccccccaaccccccaaaaaaaacccccaaaaaaccccccccccccccccccccccccccccaaaaaaccaaaaaacccccccccccccccaaaaaaaaaacaacccccjjjjjjjjjkooppppppplllcccaaacccccc +abccccccccccccccccaaaaaacccccccccccccccaaaaaaaaacccaaacaaacccccccccccccccccccccccaaaccaaccaaccaaaaccccccccccccccccaaaaaaaccaaaaaccccjjjjooooooooopuuuupppllccccaaaccccc +abccccccccccccccccccccaaccccccccccccccccaaaaaaaacccaaaccaacccccccccccccccccccccccaaaaaaacccccccaaaccccccccccccccccaaaaaaccccaaaaaaccjjjoooooooooouuuuuupplllccccaaccccc +abccaaaaccccaaacccccccccccccccccccccccccccaaaaaaaccaaccccccccccccaacccccccccccccccaaaaacccaaccaaaccccccccccccccccccccaaacccaaaaaaaccjjjoootuuuuuuuuuuuuppllllccccaccccc +abccaaaaaccaaaacccccccccccccccccccccccccccaacccacccccccccccccccacaaaacccccccccccaaaaaaacccaaaaaaacccccccccccccccccccccccccaaaaaacccciijnoottuuuuuuxxyuvpqqlmmcccccccccc +abcaaaaaaccaaaacccccccaaaaccccccccccacccccaaccccaaaccccccccccccaaaaaacccccccccccaaaaaaaaccaaaaaacccccccccccccccccaacccccccaacaaacccciiinntttxxxxuxxyyvvqqqqmmmmddddcccc +abcaaaaaacccaaacccccccaaaaccccaaaaaaaaccaaaaccccaacaacccccccccccaaaaccccccccccccaaaaaaaacccaaaaaaaacccccccccccccaaaaccccccccccaacccciiinntttxxxxxxxyyvvqqqqqmmmmdddcccc +abcaaaaaacccccccccccccaaaacccccaaaaaacccaaaaaaaaaaaaacccccccccccaaaaccccccccccccccaaacacccaaaaaaaaacccccccccccccaaaacccccccccccccccciiinnnttxxxxxxxyyvvvvqqqqmmmdddcccc +abcccaaccccccccccccccccaaccccccaaaaaacccaaaaaaaaaaaaaaccccccccccaacaccccccccccccccaaaccccaaaaaaaaaacccccccccccccaaaacccccccccccccccciiinnntttxxxxxyyyyyvvvqqqqmmmdddccc +SbccccccccccccccccccccccccccccaaaaaaaaccaaaccaaaaaaaaacccccccccccccccccccccccccccccccccccaaaaaaacccccccccaacccccccccccccccccccccccccciiinntttxxxxEzyyyyyvvvqqqmmmdddccc +abcccccccccccccccccccccccccccaaaaaaaaaacccccccaaaaaacccccccccccccaaacccccaacaacccccccccccccccaaaaaaccccccaacaaacccccccccccccccccccccciiinntttxxxyyyyyyyvvvvqqqmmmdddccc +abcccccccccccccccccccccccccccaaaaaaaaaaccccccaaaaaaaaccccccccccccaaaccccccaaaacccccccccccccccaaaaaaccccccaaaaacccccccccccccccccccccciiinnnttxxyyyyyyyvvvvvqqqqmmmdddccc +abcccccccccccccccccccccccccccacacaaacccccccccaaaaaaacccccccccccaaaaaaaacccaaaaacccccccccccccccaaaaaaaacaaaaaaccccccccccccccccccccccciiinntttxxwyyyyywwvvrrrqqmmmdddcccc +abaccccccccccccccccccccccccccccccaaacccccccccaaacaaaaacccccccccaaaaaaaaccaaaaaacccccccccccccccaaaaaaaacaaaaaaacccccccccccccccccccccchhnnnttwwwwwwwyyywvrrrrnnnnmdddcccc +abaccccccccccccccccccccccccccccccaaccccccccccccccaaaaaacccccccccaaaaaccccaaaacaccccccccccccccccaaaaacccccaaaaaaccccccaaaccccccaaaccchhnmmttswwwwwwywwwrrrrnnnnneeeccccc +abaccccccccccccccccccccccccccccccccccccccccccccccaaaaaacccccaaccaaaaaacccccaaccccccccccccccccccaaaaaaccccaaccaaccccaaaaaacccccaaacahhhmmmsssssssswwwwwrrrnnnneeeecccccc +abaaaccccccccccccccccccccccccccccaaaccccccccccccccaaaaaccccaaaccaaaaaacccccccccccccccccccccccccaaaaaaccccaaccccccccaaaaaacccaaaaaaahhhmmmmsssssssswwwwrrnnnneeeeacccccc +abaaaccccccccccccccccccccccccccccaaaaaaccccccccccaaaaacaaaaaaaccaaaccaccccccccaaaaaccccccccccccaaaacacccccccccccccccaaaaacccaaaaaaahhhhmmmmssssssswwwwrrnnneeeeaacccccc +abaaacccccccccccccccccccccccccccaaaaaaaccccccccccaaaaacaaaaaaaaaacccaaaaacccccaaaaacccccccccacaaaaaccacccccccccccccaaaaacccccaaaaaachhhmmmmmmmmmsssrrrrrnnneeeaaaaacccc +abaccccccccccccccaaaaccccccccccaaaaaaaacccccccccccccccccaaaaaaaaacccaaaaaccccaaaaaacccccccccaaaaaaaaaacccccccccccccaaaaaccccccaaaaachhhhmmmmmmmooossrrronneeeaaaaaacccc +abaccccccccccccccaaaaccccccccccaaaaaaacccccccccccccccccccaaaaaaaccccaaaaaacccaaaaaaccccaaaccaaaaaaaaaacccccccccccaaccccccccccaaaaaacchhhhhggggooooorrroonnfeeaaaaaccccc +abcccccccccccccccaaaaccccccccccccaaaaaacccccccccccccccccaaaaaaccccccaaaaaacccaaaaaaccccaaaaaacaaaaaacccccccccaaccaacccccccccccaacccccchhhhggggggoooooooooffeaaaaacccccc +abccccccccccccccccaacccccccccccccaaaaaacccccccaaccacccccaaaaaaacccccaaaaaaccccaaaccccccaaaaaacaaaaaacccccccccaaaaacccccccccccccccccccccccgggggggggooooooffffaaaaaaccccc +abccccccccccccccccccccccccccaaaccaacccccccccccaaaaacccccaaccaaacccccccaaacccccccccccccaaaaaaacaaaaaacccccccccaaaaaaaaccccccccccccccccccccccaaaggggfooooffffccccaacccccc +abaaccccccccccccccccccccccccaaacaccccccccccccaaaaacccccccccccaacccccccaaaacccaacccccccaaaaaaaaaaaaaaaccccccccccaaaaacccccccccccccaaaccccccccccccggfffffffffcccccccccccc +abaaccccccccccccccccccccccaacaaaaacccccccccccaaaaaacccccccccccccccccccaaaacaaaacccccccaaaaaaaaaccccaccccccccccaaaaaccccccccccccccaaaccccccccccccagfffffffccccccccccccca +abaacccccccaacccccccccccccaaaaaaaaccccccaacccccaaaacccccccccccccccccccaaaaaaaaacccccccccaaacaacaaacccccccccccaaacaaccccaaccaaccaaaaaaaaccccccccaaaccffffcccccccccccccaa +abaaaaaaaccaaccccccccccccccaaaaacccccccaaaacccaaccccccccccccccccccacaaaaaaaaaaccccccccccaaacaaaaaacccccccccccccccaaccccaaaaaaccaaaaaaaacccccccccaacccccccccccccccaaacaa +abaaaaaaaaaaccccccccccccccccaaaaaccccccaaaacccccccccccccccccccccccaaaaaaaaaaaaccccccccccccccaaaaaacccccccccccccccccccccaaaaaacccaaaaaacccccccccaaacccccccccccccccaaaaaa +abaaaacaaaaaaaacccccccccccccaacaaccccccaaaaccccccccccccccccccccccccaaaaaaaaaaacccccccccccccaaaaaaaacccccccccccccccccccaaaaaaaaccaaaaaaccccccccccccccccccccccccccccaaaaa diff --git a/test/aoc2022/door12_test.exs b/test/aoc2022/door12_test.exs new file mode 100644 index 0000000..5f094ea --- /dev/null +++ b/test/aoc2022/door12_test.exs @@ -0,0 +1,46 @@ +defmodule Aoc2022.Door12Test do + use Aoc2022.DoorCase + + alias Aoc2022.Door12 + + @input """ + Sabqponm + abcryxxl + accszExk + acctuvwj + abdefghi + """ + |> fake_stream() + + @input2 """ + aaabcdefghijaa + bjaSaaaaajjjkk + clltuaaaajklal + dkmsvaaaaaamam + ejmrwtsrqponmm + finqxuvwxyzEaa + ghopyzzzzzzzaa + """ + |> fake_stream() + + @input3 """ + aaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaa + SabcdefghijklmnopqrstuvwxyzE + aaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaa + """ + |> fake_stream() + + test "run_a/0" do + assert 31 == Door12.run_a(@input) + assert 28 == Door12.run_a(@input2) + assert 27 == Door12.run_a(@input3) + end + + test "run_b/0" do + assert nil == Door12.run_b(@input) + end +end From d7e20993f79ebb903ddd7d5ae7e77393cfdbd45e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Kn=C3=B6pfle?= Date: Mon, 19 Dec 2022 23:35:47 +0100 Subject: [PATCH 2/2] wip --- lib/aoc2022/door12.ex | 40 ++---------------------------------- test/aoc2022/door12_test.exs | 2 -- 2 files changed, 2 insertions(+), 40 deletions(-) diff --git a/lib/aoc2022/door12.ex b/lib/aoc2022/door12.ex index bb269a5..b0e3792 100644 --- a/lib/aoc2022/door12.ex +++ b/lib/aoc2022/door12.ex @@ -14,8 +14,8 @@ defmodule Aoc2022.Door12 do |> find_shortest_path() end - @start ?a - 1 - @goal ?z + 1 + @start ?a + @goal ?z defp convert_row(y, {?S, x}, {map, goal}), do: {Map.put(map, {x, y}, {@start, 0, nil}), goal} @@ -37,7 +37,6 @@ defmodule Aoc2022.Door12 do if min == goal do heightmap - |> print_debug(goal) |> Map.get(goal) |> elem(1) else @@ -61,41 +60,6 @@ defmodule Aoc2022.Door12 do end end - defp print_debug(heightmap, goal) do - max_x = heightmap |> Map.keys() |> Enum.map(&elem(&1, 0)) |> Enum.max() - max_y = heightmap |> Map.keys() |> Enum.map(&elem(&1, 1)) |> Enum.max() - path = build_path(heightmap, [goal]) - sparse = Map.take(heightmap, path) - - for y <- 0..max_y do - for x <- 0..max_x do - Map.get(sparse, {x, y}) - |> case do - nil -> "." - {_, _, nil} -> "S" - {_, _, {a, b}} when a + 1 == x and b == y -> ">" - {_, _, {a, b}} when a - 1 == x and b == y -> "<" - {_, _, {a, b}} when a == x and b - 1 == y -> "^" - {_, _, {a, b}} when a == x and b + 1 == y -> "v" - end - |> IO.write() - end - - IO.write("\n") - end - - heightmap - end - - def build_path(_, [nil | route]) do - route - end - - def build_path(heightmap, [last | _] = all) do - {_, _, next} = Map.get(heightmap, last) - build_path(heightmap, [next | all]) - end - def run_b(_stream) do end end diff --git a/test/aoc2022/door12_test.exs b/test/aoc2022/door12_test.exs index 5f094ea..546c68e 100644 --- a/test/aoc2022/door12_test.exs +++ b/test/aoc2022/door12_test.exs @@ -36,8 +36,6 @@ defmodule Aoc2022.Door12Test do test "run_a/0" do assert 31 == Door12.run_a(@input) - assert 28 == Door12.run_a(@input2) - assert 27 == Door12.run_a(@input3) end test "run_b/0" do