Skip to content

Instantly share code, notes, and snippets.

@hugohernani
Created February 18, 2021 03:56
Show Gist options
  • Save hugohernani/bcf3e4119e80f5a1f86478d466afdca4 to your computer and use it in GitHub Desktop.
Save hugohernani/bcf3e4119e80f5a1f86478d466afdca4 to your computer and use it in GitHub Desktop.
Elixir code example on running agent and task to create a dictionary of anagrams (extracted from Thomas Dave book)
defmodule Dictionary do
@name __MODULE__
## API
def start_link,
do: Agent.start_link(fn -> %{} end, name: @name)
def add_words(words),
do: Agent.update(@name, &do_add_words(&1, words))
def anagrams_of(word),
do: Agent.get(@name, &Map.get(&1, signature_of(word)))
## Impl
defp do_add_words(map, words),
do: Enum.reduce(words, map, &add_one_word(&1,&2))
defp add_one_word(word, map),
do: Map.update(map, signature_of(word), [word], &[word|&1])
defp signature_of(word),
do: word |> to_charlist |> Enum.sort |> to_string
end
defmodule WordlistLoader do
def load_from_files(file_names) do
file_names
|> Stream.map(fn name -> Task.async(fn -> load_task(name) end) end)
|> Enum.map(&Task.await/1)
end
defp load_task(file_name) do
File.stream!(file_name, [], :line)
|> Enum.map(&String.trim/1)
|> Dictionary.add_words
end
end
iex anagrams.exs
> Dictionary.start_link
> Enum.map(1..4, &"list#{&1}") |> WordlistLoader.load_from_files
> Dictionary.anagrams_of "organ"
angor
argon
caret
carte
cater
crate
creat
creta
ester
estre
goran
grano
groan
leapt
nagor
orang
palet
patel
pelta
petal
pleat
react
recta
reest
rogan
ronga
steer
stere
stree
terse
tsere
tepal
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment