bazybaz

bazybaz

How to get a map with its key being a tuple matching the count of all characters and its value being a list of anagrams?

Basically, what I’m trying to do is that I want a map where the key is a tuple containing count of all same characters in the list and its values being the list of anagrams. To explain it in more clearer terms, I want the following:

%{{0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0} => ['eggs', 'gegs'], {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0} => ['clay', 'alcy']}

Now, currently what I am getting is the following:

%{ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0} => "y", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0} => "s", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} => "l", {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} => "g", {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} => "e", {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} => "c", {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} => "a" }

I basically got this by writing the following code:

defmodule Anagram do
  def traverse(strings, acc \\ Map.new()) do
    Enum.reduce(strings, acc, fn string, acc ->
      string
      |> String.graphemes()
      |> Enum.reduce(acc, &Anagram.fun/2)
    end)
  end

  def fun(char, acc) do
    {index, _} = :binary.match("abcdefghijklmnopqrstuvwxyz", char)
    count = List.duplicate(0, 26)
    count = List.update_at(count, index, &(&1 + 1))
    tupcount = List.to_tuple(count)
    Map.update(acc, tupcount, count, fn _ -> char end)
  end
end

IO.inspect Anagram.traverse ["eggs", "gegs", "clay", "alcy"]

Any idea what needs to be corrected here? I’m pretty new to Elixir and experimenting with different stuff but I’m a little lost over here. Any help will be appreciated.

Most Liked

moogle19

moogle19

You could map over the graphemes to get a list of matching indexes and then reduce it to the tuple like this:

def fun(string) do
    string
    |> String.graphemes()
    |> Enum.map(fn char ->
      {index, _} = :binary.match("abcdefghijklmnopqrstuvwxyz", char)
      index
    end)
    |> Enum.reduce(List.duplicate(0, 26), fn index, list ->
      List.update_at(list, index, &(&1 + 1))
    end)
    |> List.to_tuple()
end

After then you can reduce it to a map:

def traverse(strings) do
    strings
    |> Enum.reduce(%{}, fn string, map ->
      key = fun(string)
      Map.update(map, key, [string], fn list -> list ++ [string] end)
    end)
  end
ChristianAlexander

ChristianAlexander

I took a pass at this code and extracted the key generation into a calculate_key function. Then moved map updates into the traverse function body.

defmodule Anagram do
  def traverse(strings, acc \\ Map.new()) do
    Enum.reduce(strings, acc, fn string, acc ->
      # Update the map for each string, appending to the existing list
      # if there is already a word with a matching key.
      Map.update(acc, calculate_key(string), [string], &[string | &1])
    end)
  end

  # Create a tuple from the character counts of a given word
  def calculate_key(word) do
    word
    |> String.graphemes()
    |> Enum.reduce(List.duplicate(0, 26), fn char, acc ->
      {index, _} = :binary.match("abcdefghijklmnopqrstuvwxyz", char)

      List.update_at(acc, index, &(&1 + 1))
    end)
    |> List.to_tuple()
  end
end

IO.inspect(Anagram.traverse(["eggs", "gegs", "clay", "alcy"]))

Edit: looks like @moogle19 beat me to the implementation—glad to see that someone else would approach the problem in a similar way!

Where Next?

Popular in Questions Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
pgiesin
This should be a simple problem but I just can’t seem to figure it out. I have a standalone Elixir app that won’t find the database. Dep...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New

Other popular topics Top

JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1140 51847 244
New
William
I would like to know that is there any online source for learning Phoenix Framework for building E-Commerce Store? Any advantage on build...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New

We're in Beta

About us Mission Statement