Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

day7

2020-Elixir/day7.livemd

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, &amp;[b | &amp;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(&amp;search(graph, &amp;1, accum + 1, %{visit | &amp;1 => :visit}))
      |> Enum.reduce(&amp;(&amp;1 + &amp;2))
    else
      IO.puts(accum)
      accum
    end
  end
end

lists =
  input
  |> String.split("\n")
  # replace all digits
  |> Enum.map(&amp;String.replace(&amp;1, ~r/\d/, ""))
  |> Enum.map(&amp;String.replace(&amp;1, ["bags", "bag", " ", "."], ""))
  |> Enum.map(&amp;String.split(&amp;1, ["contain", ","]))
  |> Enum.map(&amp;Graph_Gen.to_edge(&amp;1))
  |> List.flatten()
  |> Graph_Gen.to_graph()

# |> Graph_Gen.search()