day7
Mix.install([:kino])
Section
input = Kino.Input.textarea("please enter text")
input = Kino.Input.read(input)
# We will construct a graph where
# Every bag will point to the bag that contains it
defmodule Graph_Gen do
def to_edge([a, "noother"]) do
{nil, String.to_atom(a)}
end
def to_edge([a, b]) do
{String.to_atom(b), String.to_atom(a)}
end
def to_edge([head | tail]) do
for e <- tail, do: {String.to_atom(e), String.to_atom(head)}
end
def to_graph(edges) do
graph = for {a, _} <- edges, into: %{}, do: {a, []}
Enum.reduce(edges, graph, fn {a, b}, graph ->
Map.update!(graph, a, &[b | &1])
end)
end
def search(graph) do
search(graph, :shinygold, 0, %{:shinygold => :visit})
end
def search(graph, node, accum, visit) do
if Map.has_key?(graph, node) and not Map.has_key?(visit, node) do
Map.get(graph, node)
|> Enum.map(&search(graph, &1, accum + 1, %{visit | &1 => :visit}))
|> Enum.reduce(&(&1 + &2))
else
IO.puts(accum)
accum
end
end
end
lists =
input
|> String.split("\n")
# replace all digits
|> Enum.map(&String.replace(&1, ~r/\d/, ""))
|> Enum.map(&String.replace(&1, ["bags", "bag", " ", "."], ""))
|> Enum.map(&String.split(&1, ["contain", ","]))
|> Enum.map(&Graph_Gen.to_edge(&1))
|> List.flatten()
|> Graph_Gen.to_graph()
# |> Graph_Gen.search()