This commit is contained in:
Caleb Webber 2023-12-08 02:00:19 -05:00
parent 23f8a28bbd
commit 3d857d9b37
2 changed files with 103 additions and 0 deletions

76
lib/2023/day8.ex Normal file
View file

@ -0,0 +1,76 @@
defmodule Mix.Tasks.Day8 do
use Mix.Task
defp instruction_to_index("L"), do: 0
defp instruction_to_index("R"), do: 1
def walk(_, _, step, <<_::16>> <> "Z") do
step
end
def walk(instructions, nodes, step, current_location) do
l =
instructions
|> String.graphemes()
|> Enum.at(rem(step, String.length(instructions)))
index = instruction_to_index(l)
new_location = elem(Map.get(nodes, current_location), index)
walk(instructions, nodes, step + 1, new_location)
end
def loop_receive(max_len, acc) do
cond do
acc |> Enum.count() == max_len -> acc
true -> receive do
n -> loop_receive(max_len,[n | acc])
end
end
end
def run(_) do
{_, puzzle_input} = File.read("./input/2023_8.txt")
[instructions, nodes] = puzzle_input |> String.split("\n\n")
nodes =
for {key, steps} <-
nodes
|> String.split("\n")
|> Stream.reject(&(&1 == ""))
|> Stream.map(&String.split(String.trim(&1), " = "))
|> Stream.map(
&{
&1 |> Enum.at(0),
Regex.replace(~r/[\(\)]/, &1 |> Enum.at(1), "")
|> String.split(", ")
|> List.to_tuple()
}
),
into: %{} do
{key, steps}
end
parent = self()
pids = for entry <- nodes |> Map.keys() |> Enum.filter(&(&1 |> String.ends_with?("A"))) do
spawn(fn ->
send(parent,
walk(
instructions,
nodes,
0,
entry
)
)
end
)
end
loop_receive(pids |> Enum.count(), [])
|> Enum.reduce(
1,
fn a, acc ->
MathUtil.lcm(a, acc)
end
) |> IO.puts()
end
end

27
lib/math_util.ex Normal file
View file

@ -0,0 +1,27 @@
defmodule MathUtil do
@spec gcd(integer(), integer()) :: integer()
def gcd(0,0) do
0
end
@spec gcd(integer(), integer()) :: integer()
def gcd(a,a) do
a
end
@spec gcd(integer(), integer()) :: integer()
def gcd(a, b) when a > b do
gcd(a - b, b)
end
@spec gcd(integer(), integer()) :: integer()
def gcd(a, b) do
gcd(a, b - a)
end
@spec lcm(integer(), integer()) :: integer()
def lcm(a, b) do
div((a*b), gcd(a, b))
end
end