From 20501c08190aa7e8cc31223340fc9ee8a857f892 Mon Sep 17 00:00:00 2001 From: bluepython508 Date: Fri, 8 Dec 2023 14:08:39 +0000 Subject: [PATCH] Day 8 --- lib/common.ex | 3 +++ lib/day8.ex | 39 +++++++++++++++++++++++++++++++++++++++ lib/mix_tasks.ex | 5 +++-- tests/day8/1 | 9 +++++++++ tests/day8/1.1 | 1 + tests/day8/2 | 5 +++++ tests/day8/2.1 | 1 + tests/day8/3 | 10 ++++++++++ tests/day8/3.2 | 1 + 9 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 lib/day8.ex create mode 100644 tests/day8/1 create mode 100644 tests/day8/1.1 create mode 100644 tests/day8/2 create mode 100644 tests/day8/2.1 create mode 100644 tests/day8/3 create mode 100644 tests/day8/3.2 diff --git a/lib/common.ex b/lib/common.ex index 14bc967..078dd7b 100644 --- a/lib/common.ex +++ b/lib/common.ex @@ -38,4 +38,7 @@ defmodule Aoc2023.Common do def head([head | _]), do: head def tail([_ | tail]), do: tail + + def lcm(a, b), do: div(abs(a*b), Integer.gcd(a,b)) + def lcm(ls), do: ls |> Enum.reduce(&lcm/2) end diff --git a/lib/day8.ex b/lib/day8.ex new file mode 100644 index 0000000..06eadd6 --- /dev/null +++ b/lib/day8.ex @@ -0,0 +1,39 @@ +defmodule Aoc2023.Day8 do + require Integer + use Aoc2023 + + def parse(input) do + input + |> String.split("\n\n") + |> then(fn [directions, map] -> + { + directions |> String.to_charlist() |> Enum.map(&%{?L => 0, ?R => 1}[&1]), + map + |> lines + |> Enum.map(&Regex.run(~r/(\w+) = \((\w+), (\w+)\)/, &1, capture: :all_but_first)) + |> Enum.map(fn [src, dst1, dst2] -> {src, {dst1, dst2}} end) + |> Enum.into(%{}) + } + end) + end + + defp run({directions, map}, node, filter) do + directions + |> Stream.cycle() + |> Stream.scan(node, fn dir, pos -> map[pos] |> elem(dir) end) + |> Enum.find_index(filter) + |> Kernel.+(1) + end + + def part1({directions, map}) do + if map["AAA"], do: run({directions, map}, "AAA", &(&1 == "ZZZ")) + end + + def part2({directions, map}) do + map + |> Enum.map(pipe(elem(0))) + |> Enum.filter(pipe(String.ends_with?("A"))) + |> Enum.map(&run({directions, map}, &1, pipe(String.ends_with?("Z")))) + |> lcm + end +end diff --git a/lib/mix_tasks.ex b/lib/mix_tasks.ex index 208ae4e..d7d0a41 100644 --- a/lib/mix_tasks.ex +++ b/lib/mix_tasks.ex @@ -9,6 +9,7 @@ defmodule Mix.Tasks.Aoc do defp module(5), do: Aoc2023.Day5 defp module(6), do: Aoc2023.Day6 defp module(7), do: Aoc2023.Day7 + defp module(8), do: Aoc2023.Day8 # [MODULE INSERTION POINT] defp base_dir(), do: System.get_env("AOC_BASE") @@ -16,7 +17,7 @@ defmodule Mix.Tasks.Aoc do defp tests(day) do case File.ls(tests_dir(day)) do {:ok, paths} -> - paths |> Enum.filter(&(not String.contains?(&1, "."))) + paths |> Enum.filter(&(not String.contains?(&1, "."))) |> Enum.sort {:error, e} -> dbg(e) @@ -203,4 +204,4 @@ defmodule Mix.Tasks.Aoc do {:noreply, state} end end -end \ No newline at end of file +end diff --git a/tests/day8/1 b/tests/day8/1 new file mode 100644 index 0000000..9029a1b --- /dev/null +++ b/tests/day8/1 @@ -0,0 +1,9 @@ +RL + +AAA = (BBB, CCC) +BBB = (DDD, EEE) +CCC = (ZZZ, GGG) +DDD = (DDD, DDD) +EEE = (EEE, EEE) +GGG = (GGG, GGG) +ZZZ = (ZZZ, ZZZ) diff --git a/tests/day8/1.1 b/tests/day8/1.1 new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/tests/day8/1.1 @@ -0,0 +1 @@ +2 diff --git a/tests/day8/2 b/tests/day8/2 new file mode 100644 index 0000000..7d1b58d --- /dev/null +++ b/tests/day8/2 @@ -0,0 +1,5 @@ +LLR + +AAA = (BBB, BBB) +BBB = (AAA, ZZZ) +ZZZ = (ZZZ, ZZZ) diff --git a/tests/day8/2.1 b/tests/day8/2.1 new file mode 100644 index 0000000..1e8b314 --- /dev/null +++ b/tests/day8/2.1 @@ -0,0 +1 @@ +6 diff --git a/tests/day8/3 b/tests/day8/3 new file mode 100644 index 0000000..5b3fa58 --- /dev/null +++ b/tests/day8/3 @@ -0,0 +1,10 @@ +LR + +11A = (11B, XXX) +11B = (XXX, 11Z) +11Z = (11B, XXX) +22A = (22B, XXX) +22B = (22C, 22C) +22C = (22Z, 22Z) +22Z = (22B, 22B) +XXX = (XXX, XXX) diff --git a/tests/day8/3.2 b/tests/day8/3.2 new file mode 100644 index 0000000..1e8b314 --- /dev/null +++ b/tests/day8/3.2 @@ -0,0 +1 @@ +6