mirror of
https://github.com/Xevion/exercism.git
synced 2025-12-06 05:15:02 -06:00
word count elixir
This commit is contained in:
1
elixir/word-count/.exercism/metadata.json
Normal file
1
elixir/word-count/.exercism/metadata.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"track":"elixir","exercise":"word-count","id":"63352c9e75ce4e9493107876d43de14a","url":"https://exercism.io/my/solutions/63352c9e75ce4e9493107876d43de14a","handle":"Xevion","is_requester":true,"auto_approve":false}
|
||||||
4
elixir/word-count/.formatter.exs
Normal file
4
elixir/word-count/.formatter.exs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Used by "mix format"
|
||||||
|
[
|
||||||
|
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||||
|
]
|
||||||
24
elixir/word-count/.gitignore
vendored
Normal file
24
elixir/word-count/.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# The directory Mix will write compiled artifacts to.
|
||||||
|
/_build/
|
||||||
|
|
||||||
|
# If you run "mix test --cover", coverage assets end up here.
|
||||||
|
/cover/
|
||||||
|
|
||||||
|
# The directory Mix downloads your dependencies sources to.
|
||||||
|
/deps/
|
||||||
|
|
||||||
|
# Where third-party dependencies like ExDoc output generated docs.
|
||||||
|
/doc/
|
||||||
|
|
||||||
|
# Ignore .fetch files in case you like to edit your project deps locally.
|
||||||
|
/.fetch
|
||||||
|
|
||||||
|
# If the VM crashes, it generates a dump, let's ignore it too.
|
||||||
|
erl_crash.dump
|
||||||
|
|
||||||
|
# Also ignore archive artifacts (built via "mix archive.build").
|
||||||
|
*.ez
|
||||||
|
|
||||||
|
# Ignore package tarball (built via "mix hex.build").
|
||||||
|
word_count-*.tar
|
||||||
|
|
||||||
57
elixir/word-count/README.md
Normal file
57
elixir/word-count/README.md
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# Word Count
|
||||||
|
|
||||||
|
Given a phrase, count the occurrences of each word in that phrase.
|
||||||
|
|
||||||
|
For example for the input `"olly olly in come free"`
|
||||||
|
|
||||||
|
```text
|
||||||
|
olly: 2
|
||||||
|
in: 1
|
||||||
|
come: 1
|
||||||
|
free: 1
|
||||||
|
```
|
||||||
|
|
||||||
|
Words are compared case-insensitively.
|
||||||
|
The keys are lowercase.
|
||||||
|
|
||||||
|
## Running tests
|
||||||
|
|
||||||
|
Execute the tests with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ 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:
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
# @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.
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
# ExUnit.configure exclude: :pending, trace: true
|
||||||
|
```
|
||||||
|
|
||||||
|
If you're stuck on something, it may help to look at some of
|
||||||
|
the [available resources](https://exercism.io/tracks/elixir/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.
|
||||||
17
elixir/word-count/lib/word_count.ex
Normal file
17
elixir/word-count/lib/word_count.ex
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
defmodule WordCount do
|
||||||
|
@splitters String.graphemes(" _!&@:;'\"[]()_=+,$&%^")
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Count the number of words in the sentence.
|
||||||
|
|
||||||
|
Words are compared case-insensitively.
|
||||||
|
"""
|
||||||
|
@spec count(String.t()) :: map
|
||||||
|
def count(sentence) do
|
||||||
|
sentence
|
||||||
|
|> String.downcase()
|
||||||
|
|> String.split(@splitters)
|
||||||
|
|> Enum.filter(&(String.length(&1) > 0))
|
||||||
|
|> Enum.reduce(%{}, fn (word, count) -> Map.update(count, word, 1, &(&1 + 1)) end)
|
||||||
|
end
|
||||||
|
end
|
||||||
28
elixir/word-count/mix.exs
Normal file
28
elixir/word-count/mix.exs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
defmodule WordCount.MixProject do
|
||||||
|
use Mix.Project
|
||||||
|
|
||||||
|
def project do
|
||||||
|
[
|
||||||
|
app: :word_count,
|
||||||
|
version: "0.1.0",
|
||||||
|
# elixir: "~> 1.8",
|
||||||
|
start_permanent: Mix.env() == :prod,
|
||||||
|
deps: deps()
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Run "mix help compile.app" to learn about applications.
|
||||||
|
def application do
|
||||||
|
[
|
||||||
|
extra_applications: [:logger]
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Run "mix help deps" to learn about dependencies.
|
||||||
|
defp deps do
|
||||||
|
[
|
||||||
|
# {:dep_from_hexpm, "~> 0.3.0"},
|
||||||
|
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
2
elixir/word-count/test/test_helper.exs
Normal file
2
elixir/word-count/test/test_helper.exs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ExUnit.start()
|
||||||
|
# ExUnit.configure(exclude: :pending, trace: true)
|
||||||
55
elixir/word-count/test/word_count_test.exs
Normal file
55
elixir/word-count/test/word_count_test.exs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
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
|
||||||
Reference in New Issue
Block a user