Initial commit
This commit is contained in:
24
elixir/language-list/.exercism/config.json
Normal file
24
elixir/language-list/.exercism/config.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"authors": [
|
||||
"neenjaw"
|
||||
],
|
||||
"contributors": [
|
||||
"fireproofsocks"
|
||||
],
|
||||
"files": {
|
||||
"solution": [
|
||||
"lib/language_list.ex"
|
||||
],
|
||||
"test": [
|
||||
"test/language_list_test.exs"
|
||||
],
|
||||
"exemplar": [
|
||||
".meta/exemplar.ex"
|
||||
]
|
||||
},
|
||||
"language_versions": ">=1.10",
|
||||
"forked_from": [
|
||||
"clojure/tracks-on-tracks-on-tracks"
|
||||
],
|
||||
"blurb": "Learn about lists by keeping track of the programming languages you're currently learning on Exercism."
|
||||
}
|
||||
1
elixir/language-list/.exercism/metadata.json
Normal file
1
elixir/language-list/.exercism/metadata.json
Normal file
@@ -0,0 +1 @@
|
||||
{"track":"elixir","exercise":"language-list","id":"1fc6fd5b991141188a10438edd755faa","url":"https://exercism.org/tracks/elixir/exercises/language-list","handle":"negrienko","is_requester":true,"auto_approve":false}
|
||||
4
elixir/language-list/.formatter.exs
Normal file
4
elixir/language-list/.formatter.exs
Normal file
@@ -0,0 +1,4 @@
|
||||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
||||
24
elixir/language-list/.gitignore
vendored
Normal file
24
elixir/language-list/.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").
|
||||
strings-*.tar
|
||||
|
||||
75
elixir/language-list/HELP.md
Normal file
75
elixir/language-list/HELP.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Help
|
||||
|
||||
## Running the tests
|
||||
|
||||
From the terminal, change to the base directory of the exercise then execute the tests with:
|
||||
|
||||
```bash
|
||||
$ mix test
|
||||
```
|
||||
|
||||
This will execute the test file found in the `test` subfolder -- a file ending in `_test.exs`
|
||||
|
||||
Documentation:
|
||||
|
||||
* [`mix test` - Elixir's test execution tool](https://hexdocs.pm/mix/Mix.Tasks.Test.html)
|
||||
* [`ExUnit` - Elixir's unit test library](https://hexdocs.pm/ex_unit/ExUnit.html)
|
||||
|
||||
## Pending tests
|
||||
|
||||
In test suites of practice exercises, all but the first test have been tagged to be 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
|
||||
```
|
||||
|
||||
If you wish to run all tests at once, you can include all skipped test by using the `--include` flag on the `mix test` command:
|
||||
|
||||
```bash
|
||||
$ mix test --include pending
|
||||
```
|
||||
|
||||
Or, you can enable all the tests by commenting out the `ExUnit.configure` line in the file `test/test_helper.exs`.
|
||||
|
||||
```elixir
|
||||
# ExUnit.configure(exclude: :pending, trace: true)
|
||||
```
|
||||
|
||||
## Useful `mix test` options
|
||||
|
||||
* `test/<FILE>.exs:LINENUM` - runs only a single test, the test from `<FILE>.exs` whose definition is on line `LINENUM`
|
||||
* `--failed` - runs only tests that failed the last time they ran
|
||||
* `--max-failures` - the suite stops evaluating tests when this number of test failures
|
||||
is reached
|
||||
* `--seed 0` - disables randomization so the tests in a single file will always be ran
|
||||
in the same order they were defined in
|
||||
|
||||
## Submitting your solution
|
||||
|
||||
You can submit your solution using the `exercism submit lib/language_list.ex` command.
|
||||
This command will upload your solution to the Exercism website and print the solution page's URL.
|
||||
|
||||
It's possible to submit an incomplete solution which allows you to:
|
||||
|
||||
- See how others have completed the exercise
|
||||
- Request help from a mentor
|
||||
|
||||
## Need to get help?
|
||||
|
||||
If you'd like help solving the exercise, check the following pages:
|
||||
|
||||
- The [Elixir track's documentation](https://exercism.org/docs/tracks/elixir)
|
||||
- The [Elixir track's programming category on the forum](https://forum.exercism.org/c/programming/elixir)
|
||||
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
|
||||
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
|
||||
|
||||
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
|
||||
|
||||
If you're stuck on something, it may help to look at some of the [available resources](https://exercism.org/docs/tracks/elixir/resources) out there where answers might be found.
|
||||
35
elixir/language-list/HINTS.md
Normal file
35
elixir/language-list/HINTS.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Hints
|
||||
|
||||
## General
|
||||
|
||||
- Use the built-in [(linked) list type][list].
|
||||
|
||||
## 1. Define a function to return an empty language list
|
||||
|
||||
- The function needs to return `[]`.
|
||||
|
||||
## 2. Define a function to add a language to the list
|
||||
|
||||
- An element can be prepended to a list using `|`.
|
||||
|
||||
## 3. Define a function to remove a language from the list
|
||||
|
||||
- Elixir [provides a function][tl] to return a list with the first item removed.
|
||||
|
||||
## 4. Define a function to return the first item in the list
|
||||
|
||||
- Elixir [provides a function][hd] to get the first item from a list.
|
||||
|
||||
## 5. Define a function to return how many languages are in the list
|
||||
|
||||
- Elixir [provides a function][length] to count the length of a list.
|
||||
|
||||
## 6. Define a function to determine if the list includes a functional language
|
||||
|
||||
- Your function should return a boolean value indicating whether `"Elixir"` is a member of the list. Elixir [provides a function][in] to test list membership.
|
||||
|
||||
[list]: https://elixir-lang.org/getting-started/basic-types.html#linked-lists
|
||||
[hd]: https://hexdocs.pm/elixir/Kernel.html#hd/1
|
||||
[tl]: https://hexdocs.pm/elixir/Kernel.html#tl/1
|
||||
[length]: https://hexdocs.pm/elixir/Kernel.html#length/1
|
||||
[in]: https://hexdocs.pm/elixir/Kernel.html#in/2
|
||||
140
elixir/language-list/README.md
Normal file
140
elixir/language-list/README.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# Language List
|
||||
|
||||
Welcome to Language List on Exercism's Elixir Track.
|
||||
If you need help running the tests or submitting your code, check out `HELP.md`.
|
||||
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
|
||||
|
||||
## Introduction
|
||||
|
||||
## Lists
|
||||
|
||||
Lists are built-in to the Elixir language. They are considered a basic type, denoted by square brackets. Lists may be empty or hold any number of items of any type. For example:
|
||||
|
||||
```elixir
|
||||
empty_list = []
|
||||
one_item_list = [1]
|
||||
two_item_list = [1, 2]
|
||||
multiple_type_list = [1, :pi, 3.14, "four"]
|
||||
```
|
||||
|
||||
Elixir implements lists as a linked list, where each node stores two values: the first item and another list with all the remaining items. The first item in the list is referred to as the _head_ and the remaining list of items is called the _tail_. We can use this notation in code:
|
||||
|
||||
```elixir
|
||||
# [1] represented in [head | tail] notation
|
||||
[1 | []]
|
||||
|
||||
# [1, 2, 3] represented in [head | tail] notation
|
||||
[1 | [2 | [3 | []]]]
|
||||
```
|
||||
|
||||
We can use _`[head | tail]`_ notation to prepend elements to a list:
|
||||
|
||||
```elixir
|
||||
# Suppose
|
||||
list = [2, 1]
|
||||
|
||||
[3, 2, 1] == [3 | list]
|
||||
# => true
|
||||
```
|
||||
|
||||
There are several functions in the `Kernel` module for working with lists, as well as the whole `List` module.
|
||||
|
||||
```elixir
|
||||
# Check if 1 is a member of the list
|
||||
1 in [1, 2, 3, 4]
|
||||
# => true
|
||||
```
|
||||
|
||||
## Instructions
|
||||
|
||||
In this exercise you need to implement some functions to manipulate a list of programming languages.
|
||||
|
||||
## 1. Define a function to return an empty language list
|
||||
|
||||
Define the `new/0` function that takes no arguments and returns an empty list.
|
||||
|
||||
```elixir
|
||||
LanguageList.new()
|
||||
# => []
|
||||
```
|
||||
|
||||
## 2. Define a function to add a language to the list
|
||||
|
||||
Define the `add/2` function that takes 2 arguments (a _language list_ and a string literal of a _language_). It should return the resulting list with the new language prepended to the given list.
|
||||
|
||||
```elixir
|
||||
language_list = LanguageList.new()
|
||||
# => []
|
||||
language_list = LanguageList.add(language_list, "Clojure")
|
||||
# => ["Clojure"]
|
||||
language_list = LanguageList.add(language_list, "Haskell")
|
||||
# => ["Haskell", "Clojure"]
|
||||
```
|
||||
|
||||
## 3. Define a function to remove a language from the list
|
||||
|
||||
Define the `remove/1` function that takes 1 argument (a _language list_). It should return the list without the first item. Assume the list will always have at least one item.
|
||||
|
||||
```elixir
|
||||
language_list = LanguageList.new()
|
||||
# => []
|
||||
language_list = LanguageList.add(language_list, "Clojure")
|
||||
# => ["Clojure"]
|
||||
language_list = LanguageList.add(language_list, "Haskell")
|
||||
# => ["Haskell", "Clojure"]
|
||||
language_list = LanguageList.remove(language_list)
|
||||
# => ["Clojure"]
|
||||
```
|
||||
|
||||
## 4. Define a function to return the first item in the list
|
||||
|
||||
Define the `first/1` function that takes 1 argument (a _language list_). It should return the first language in the list. Assume the list will always have at least one item.
|
||||
|
||||
```elixir
|
||||
language_list = LanguageList.new()
|
||||
# => []
|
||||
language_list = LanguageList.add(language_list, "Elm")
|
||||
# => ["Elm"]
|
||||
language_list = LanguageList.add(language_list, "Prolog")
|
||||
# => ["Prolog", "Elm"]
|
||||
LanguageList.first(language_list)
|
||||
# => "Prolog"
|
||||
```
|
||||
|
||||
## 5. Define a function to return how many languages are in the list
|
||||
|
||||
Define the `count/1` function that takes 1 argument (a _language list_). It should return the number of languages in the list.
|
||||
|
||||
```elixir
|
||||
language_list = LanguageList.new()
|
||||
# => []
|
||||
language_list = LanguageList.add(language_list, "Elm")
|
||||
# => ["Elm"]
|
||||
language_list = LanguageList.add(language_list, "Prolog")
|
||||
# => ["Prolog", "Elm"]
|
||||
LanguageList.count(language_list)
|
||||
# => 2
|
||||
```
|
||||
|
||||
## 6. Define a function to determine if the list includes a functional language
|
||||
|
||||
Define the `functional_list?/1` function which takes 1 argument (a _language list_). It should return a boolean value. It should return true if _"Elixir"_ is one of the languages in the list.
|
||||
|
||||
```elixir
|
||||
language_list = LanguageList.new()
|
||||
# => []
|
||||
language_list = LanguageList.add(language_list, "Elixir")
|
||||
# => ["Elixir"]
|
||||
LanguageList.functional_list?(language_list)
|
||||
# => true
|
||||
```
|
||||
|
||||
## Source
|
||||
|
||||
### Created by
|
||||
|
||||
- @neenjaw
|
||||
|
||||
### Contributed to by
|
||||
|
||||
- @fireproofsocks
|
||||
13
elixir/language-list/lib/language_list.ex
Normal file
13
elixir/language-list/lib/language_list.ex
Normal file
@@ -0,0 +1,13 @@
|
||||
defmodule LanguageList do
|
||||
def new(), do: []
|
||||
|
||||
def add(list, language), do: [language | list]
|
||||
|
||||
def remove(list), do: tl(list)
|
||||
|
||||
def first(list), do: hd(list)
|
||||
|
||||
def count(list), do: length(list)
|
||||
|
||||
def functional_list?(list), do: "Elixir" in list
|
||||
end
|
||||
28
elixir/language-list/mix.exs
Normal file
28
elixir/language-list/mix.exs
Normal file
@@ -0,0 +1,28 @@
|
||||
defmodule LanguageList.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :language_list,
|
||||
version: "0.1.0",
|
||||
# elixir: "~> 1.10",
|
||||
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
|
||||
116
elixir/language-list/test/language_list_test.exs
Normal file
116
elixir/language-list/test/language_list_test.exs
Normal file
@@ -0,0 +1,116 @@
|
||||
defmodule LanguageListTest do
|
||||
use ExUnit.Case
|
||||
|
||||
describe "new/0" do
|
||||
@tag task_id: 1
|
||||
test "new list" do
|
||||
assert LanguageList.new() == []
|
||||
end
|
||||
end
|
||||
|
||||
describe "add/2" do
|
||||
@tag task_id: 2
|
||||
test "add a language to a list" do
|
||||
language = "Elixir"
|
||||
list = [language]
|
||||
|
||||
assert LanguageList.new() |> LanguageList.add(language) == list
|
||||
end
|
||||
|
||||
@tag task_id: 2
|
||||
test "add several languages to a list" do
|
||||
list =
|
||||
LanguageList.new()
|
||||
|> LanguageList.add("Clojure")
|
||||
|> LanguageList.add("Haskell")
|
||||
|> LanguageList.add("Erlang")
|
||||
|> LanguageList.add("F#")
|
||||
|> LanguageList.add("Elixir")
|
||||
|
||||
assert list == ["Elixir", "F#", "Erlang", "Haskell", "Clojure"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "remove/1" do
|
||||
@tag task_id: 3
|
||||
test "add then remove results in empty list" do
|
||||
list =
|
||||
LanguageList.new()
|
||||
|> LanguageList.add("Elixir")
|
||||
|> LanguageList.remove()
|
||||
|
||||
assert list == []
|
||||
end
|
||||
|
||||
@tag task_id: 3
|
||||
test "adding two languages, when removed, removes first item" do
|
||||
list =
|
||||
LanguageList.new()
|
||||
|> LanguageList.add("F#")
|
||||
|> LanguageList.add("Elixir")
|
||||
|> LanguageList.remove()
|
||||
|
||||
assert list == ["F#"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "first/1" do
|
||||
@tag task_id: 4
|
||||
test "add one language, then get the first" do
|
||||
assert LanguageList.new() |> LanguageList.add("Elixir") |> LanguageList.first() == "Elixir"
|
||||
end
|
||||
|
||||
@tag task_id: 4
|
||||
test "add a few languages, then get the first" do
|
||||
first =
|
||||
LanguageList.new()
|
||||
|> LanguageList.add("Elixir")
|
||||
|> LanguageList.add("Prolog")
|
||||
|> LanguageList.add("F#")
|
||||
|> LanguageList.first()
|
||||
|
||||
assert first == "F#"
|
||||
end
|
||||
end
|
||||
|
||||
describe "count/1" do
|
||||
@tag task_id: 5
|
||||
test "the count of a new list is 0" do
|
||||
assert LanguageList.new() |> LanguageList.count() == 0
|
||||
end
|
||||
|
||||
@tag task_id: 5
|
||||
test "the count of a one-language list is 1" do
|
||||
count =
|
||||
LanguageList.new()
|
||||
|> LanguageList.add("Elixir")
|
||||
|> LanguageList.count()
|
||||
|
||||
assert count == 1
|
||||
end
|
||||
|
||||
@tag task_id: 5
|
||||
test "the count of a multiple-item list is equal to its length" do
|
||||
count =
|
||||
LanguageList.new()
|
||||
|> LanguageList.add("Elixir")
|
||||
|> LanguageList.add("Prolog")
|
||||
|> LanguageList.add("F#")
|
||||
|> LanguageList.count()
|
||||
|
||||
assert count == 3
|
||||
end
|
||||
end
|
||||
|
||||
describe "functional_list?/1" do
|
||||
@tag task_id: 6
|
||||
test "a functional language list" do
|
||||
assert LanguageList.functional_list?(["Clojure", "Haskell", "Erlang", "F#", "Elixir"])
|
||||
end
|
||||
|
||||
@tag task_id: 6
|
||||
test "not a functional language list" do
|
||||
refute LanguageList.functional_list?(["Java", "C", "JavaScript"])
|
||||
end
|
||||
end
|
||||
end
|
||||
2
elixir/language-list/test/test_helper.exs
Normal file
2
elixir/language-list/test/test_helper.exs
Normal file
@@ -0,0 +1,2 @@
|
||||
ExUnit.start()
|
||||
ExUnit.configure(exclude: :pending, trace: true, seed: 0)
|
||||
Reference in New Issue
Block a user