 # PatrickMcSweeny's solution

## to Word Count in the Elixir Track

Published at Dec 07 2019 · 0 comments
Instructions
Test suite
Solution

Given a phrase, count the occurrences of each word in that phrase.

For example for the input `"olly olly in come free"`

``````olly: 2
in: 1
come: 1
free: 1
``````

Words are compared case-insensitively. The keys are lowercase.

## Running tests

Execute the tests with:

``````\$ mix test
``````

### Pending tests

In the test suites, all but the first test have been skipped.

Once you get a test passing, you can unskip the next one by commenting out the relevant `@tag :pending` with a `#` symbol.

For example:

``````# @tag :pending
test "shouting" do
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
end
``````

Or, you can enable all the tests by commenting out the `ExUnit.configure` line in the test suite.

``````# ExUnit.configure exclude: :pending, trace: true
``````

If you're stuck on something, it may help to look at some of the available resources out there where answers might be found.

## Source

This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour.

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### test_helper.exs

``````ExUnit.start()
ExUnit.configure(exclude: :pending, trace: true)``````

### word_count_test.exs

``````defmodule WordCountTest do
use ExUnit.Case

test "count one word" do
assert WordCount.count("word") == %{"word" => 1}
end

@tag :pending
test "count one of each" do
expected = %{"one" => 1, "of" => 1, "each" => 1}
assert WordCount.count("one of each") == expected
end

@tag :pending
test "count multiple occurrences" do
expected = %{"one" => 1, "fish" => 4, "two" => 1, "red" => 1, "blue" => 1}
assert WordCount.count("one fish two fish red fish blue fish") == expected
end

@tag :pending
test "ignore punctuation" do
expected = %{"car" => 1, "carpet" => 1, "as" => 1, "java" => 1, "javascript" => 1}
assert WordCount.count("car : carpet as java : javascript!!&@\$%^&") == expected
end

@tag :pending
test "include numbers" do
expected = %{"testing" => 2, "1" => 1, "2" => 1}
assert WordCount.count("testing, 1, 2 testing") == expected
end

@tag :pending
test "hyphens" do
expected = %{"co-operative" => 1}
assert WordCount.count("co-operative") == expected
end

@tag :pending
test "ignore underscores" do
expected = %{"two" => 1, "words" => 1}
assert WordCount.count("two_words") == expected
end

@tag :pending
test "normalize case" do
expected = %{"go" => 3}
assert WordCount.count("go Go GO") == expected
end

@tag :pending
test "German" do
expected = %{"götterfunken" => 1, "schöner" => 1, "freude" => 1}
assert WordCount.count("Freude schöner Götterfunken") == expected
end
end``````
``````defmodule WordCount do
@doc """
Count the number of words in the sentence.

Words are compared case-insensitively.
"""
@spec count(String.t()) :: map
def count(sentence) do
words = Regex.scan(~r/[[:alnum:]|\-|ö]+/,	String.downcase(sentence))
Enum.into(words, %{}, fn word ->
{Enum.at(word, 0), Enum.count(words, fn w -> w == word end)}
end)
end
end``````