diff --git a/2021/README.md b/2021/README.md index c63d455..fb040e3 100644 --- a/2021/README.md +++ b/2021/README.md @@ -16,7 +16,7 @@ | :-: | :-: | :-: | :-: | :-: | :-: | :-: | | | | | [1] | [2] | [3] | [4] | | [5] | [6] | [7] | [8] | [9] | [10] | [11]| -| 12 | 13 | 14 | 15 | 16 | 17 | 18 | +| [12]| 13 | 14 | 15 | 16 | 17 | 18 | | 19 | 20 | 21 | 22 | 23 | 24 | 25 | @@ -32,3 +32,4 @@ [9]: ./lib/2021/9.ex [10]: ./lib/2021/10.ex [11]: ./lib/2021/11.ex +[12]: ./lib/2021/12.ex diff --git a/2021/lib/2021/12.ex b/2021/lib/2021/12.ex new file mode 100644 index 0000000..b3d342d --- /dev/null +++ b/2021/lib/2021/12.ex @@ -0,0 +1,68 @@ +import AOC + +aoc 2021, 12 do + @target "end" + + def input_graph() do + input_stream() + |> Enum.reduce(Graph.new(type: :undirected), fn line, graph -> + [l, r] = String.split(line, "-", trim: true) + Graph.add_edge(graph, l, r) + end) + end + + def all_paths(graph, can_visit?, curr \\ "start", path \\ ["start"]) + def all_paths(_graph, _can_visit?, @target, path), do: [path] + + def all_paths(graph, can_visit?, curr, path) do + neighbors = Graph.neighbors(graph, curr) + + if Enum.empty?(neighbors) do + [] + else + neighbors + |> Enum.flat_map(fn neighbor -> + if can_visit?.(neighbor, path) do + all_paths(graph, can_visit?, neighbor, [neighbor | path]) + else + [] + end + end) + end + end + + def cave_is_big?(cave), do: String.upcase(cave) == cave + + def p1 do + input_graph() + |> all_paths(fn cave, path -> cave_is_big?(cave) or cave not in path end) + |> length() + end + + def p2 do + input_graph() + |> all_paths(fn cave, path -> + if cave_is_big?(cave) do + true + else + if cave not in path do + true + else + if cave in ["start", "end"] do + false + else + max_small_cave_in_path = + path + |> Enum.reject(&cave_is_big?/1) + |> Enum.frequencies() + |> Map.values() + |> Enum.max() + + max_small_cave_in_path < 2 + end + end + end + end) + |> length() + end +end diff --git a/2021/mix.exs b/2021/mix.exs index eaea687..2f15207 100644 --- a/2021/mix.exs +++ b/2021/mix.exs @@ -28,6 +28,7 @@ defmodule AdventOfCode.MixProject do {:advent_of_code_utils, "~> 1.0"}, {:benchee, "~> 1.0", only: :dev}, {:exla, "~> 0.1.0-dev", github: "elixir-nx/nx", sparse: "exla"}, + {:libgraph, "~> 0.13.3"}, {:nimble_parsec, "~> 1.0"}, {:nx, "~> 0.1.0-dev", github: "elixir-nx/nx", sparse: "nx", override: true}, {:rexbug, ">= 1.0.0"} diff --git a/2021/mix.lock b/2021/mix.lock index 5d2a4a3..7abba06 100644 --- a/2021/mix.lock +++ b/2021/mix.lock @@ -8,6 +8,7 @@ "exla": {:git, "https://github.com/elixir-nx/nx.git", "e23a678bf0ebcbbafe03f1b5ed78623f052ad486", [sparse: "exla"]}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, "finch": {:hex, :finch, "0.9.0", "8b772324aebafcaba763f1dffaa3e7f52f8c4e52485f50f48bbb2f42219a2e87", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.3.5", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a93bfcad9ca50fa3cb2d459f27667d9a87cfbb7fecf9b29b2e78a50bc2ab445d"}, + "libgraph": {:hex, :libgraph, "0.13.3", "20732b7bafb933dcf7351c479e03076ebd14a85fd3202c67a1c197f4f7c2466b", [:mix], [], "hexpm", "78f2576eef615440b46f10060b1de1c86640441422832052686df53dc3c148c6"}, "mint": {:hex, :mint, "1.4.0", "cd7d2451b201fc8e4a8fd86257fb3878d9e3752899eb67b0c5b25b180bde1212", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "10a99e144b815cbf8522dccbc8199d15802440fc7a64d67b6853adb6fa170217"}, "mix_test_interactive": {:hex, :mix_test_interactive, "1.1.0", "e3e048ea8b56637c8e5614044483e11d78f81f70e9afb811c06ad3db69704c32", [:mix], [{:file_system, "~> 0.2", [hex: :file_system, repo: "hexpm", optional: false]}, {:typed_struct, "~> 0.2.1", [hex: :typed_struct, repo: "hexpm", optional: false]}], "hexpm", "2288a2edc735ca4879a7c17b9fd9fd4b8b84a57a775c3228db4655806a0a4799"}, "nimble_options": {:hex, :nimble_options, "0.3.7", "1e52dd7673d36138b1a5dede183b5d86dff175dc46d104a8e98e396b85b04670", [:mix], [], "hexpm", "2086907e6665c6b6579be54ef5001928df5231f355f71ed258f80a55e9f63633"},