diff --git a/06_breadth-first_search/elixir/01_breadth-first_search.exs b/06_breadth-first_search/elixir/01_breadth-first_search.exs new file mode 100644 index 0000000..75a54fe --- /dev/null +++ b/06_breadth-first_search/elixir/01_breadth-first_search.exs @@ -0,0 +1,52 @@ +defmodule BreadthFirstSearch do + def search(graph, initial_vertex, search_fn) do + initial_search_queue = list_to_queue(graph[initial_vertex]) + do_search(initial_search_queue, search_fn, [], graph) + end + + defp do_search(_empty_queue = {[], []}, _, _, _), do: nil + + defp do_search(search_queue, search_fn, searched_list, graph) do + {{:value, value}, rest_queue} = :queue.out(search_queue) + + cond do + value in searched_list -> + do_search(rest_queue, search_fn, searched_list, graph) + + search_fn.(value) -> + value + + true -> + continue_search(rest_queue, value, search_fn, searched_list, graph) + end + end + + defp continue_search(search_queue, value, search_fn, searched_list, graph) do + join_with_search_queue = &:queue.join(search_queue, &1) + + updated_search_queue = + graph[value] + |> list_to_queue() + |> join_with_search_queue.() + + do_search(updated_search_queue, search_fn, [value | searched_list], graph) + end + + defp list_to_queue(list), do: :queue.from_list(list) +end + +graph = %{ + "you" => ["alice", "bob", "claire"], + "bob" => ["anuj", "peggy"], + "alice" => ["peggy"], + "claire" => ["thom", "jonny"], + "anuj" => [], + "peggy" => [], + "thom" => [], + "jonny" => [] +} + +person_is_seller? = &String.ends_with?(&1, "m") + +name = BreadthFirstSearch.search(graph, "you", person_is_seller?) +IO.puts("#{name} is a mango seller!")