Skip to content

Instantly share code, notes, and snippets.

@redroot
Last active February 22, 2018 11:17
Show Gist options
  • Select an option

  • Save redroot/790c450eacb35471c43f28a8f60bc2ac to your computer and use it in GitHub Desktop.

Select an option

Save redroot/790c450eacb35471c43f28a8f60bc2ac to your computer and use it in GitHub Desktop.
Adjacent letters in word list
# what I want - from this word list, a map of letters -> list of adjacent letters e.g. { "B" => ["A"], "X" => ["U", "O"] }
words = ["BAKERY", "DERV", "FAUX", "HOME", "JUMPY", "PHLOX", "QUAGMIRE", "SWIM", "UPON", "WRECK", "WRIST"]
all_letters = for n <- ?A..?Y, do: << n :: utf8 >>
# produces ["A", "B", "C", ...]
initial_letter_map = List.duplicate([], 25) |> (&List.zip([all_letters, &1])).() |> Map.new
# produces { "A" => [], "B" => [] } etc
letter_pairs = Enum.flat_map(words, fn(word) ->
Enum.map((0..String.length(word) - 2), fn(index) ->
{ String.slice(word, index, 1), String.slice(word, index+1, 1) }
end)
end)
# produces [{"B","A"},{"A","K"},{"K","E"}...] flatten across all words, with duplicates
Enum.reduce(letter_pairs, initial_letter_map, fn({ first, second }, acc) ->
acc
|> Map.update!(first, fn l -> Enum.uniq(l ++ [second]) end)
|> Map.update!(second, fn l -> Enum.uniq(l ++ [first]) end)
end)
# produces %{
# "A" => ["B", "K", "F", "U", "G"],
# "B" => ["A"],
# "C" => ["E", "K"]
# ... etc
# }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment