diff --git a/exercises/anagram.livemd b/exercises/anagram.livemd index 99d40a44d..af3db1a5c 100644 --- a/exercises/anagram.livemd +++ b/exercises/anagram.livemd @@ -67,6 +67,7 @@ defmodule Anagram do true """ def anagram?(string1, string2) do + String.to_charlist(string1) |> Enum.sort() == String.to_charlist(string2) |> Enum.sort() end @doc """ @@ -84,6 +85,7 @@ defmodule Anagram do [] """ def filter_anagrams(word_list, anagram) do + Enum.filter(word_list, fn word -> anagram?(word, anagram) end) end end ``` diff --git a/exercises/animal_generator.livemd b/exercises/animal_generator.livemd index 81d96f88c..12d9cc543 100644 --- a/exercises/animal_generator.livemd +++ b/exercises/animal_generator.livemd @@ -57,7 +57,13 @@ end Enter your solution below. ```elixir +names = ["Clifford", "Zoboomafoo", "Leonardo"] +animal_types = ["dog", "lemur", "turtle"] +ages = 1..14 +for name <- names, animal_type <- animal_types, age <- ages do + %{name: name, animal_type: animal_type, age: age} +end ``` ## Mark As Completed diff --git a/exercises/battle_map.livemd b/exercises/battle_map.livemd index 2a1b783fc..cfd4781cc 100644 --- a/exercises/battle_map.livemd +++ b/exercises/battle_map.livemd @@ -130,6 +130,22 @@ defprotocol Character do def can_attack?(character, origin, target) end +defimpl Character, for: Barbarian do + def can_attack?(_character, {x1, y1}, {x2, y2}) do + # can move +/- 2 spaces along the x axis -> horizontal + # can move +/- 2 spaces along the y axis -> vertical + # horizontal # vertical + abs(x2 - x1) <= 2 or abs(y2 - y1) <= 2 + end +end + +defimpl Character, for: Wizard do + def can_attack?(_character, {x1, y1}, {x2, y2}) do + # vertical/horizontal # diagonal + x1 == x2 || y1 == y2 || abs(x2 - x1) == abs(y2 - y1) + end +end + ExUnit.start(auto_run: false) defmodule CharacterTests do @@ -198,7 +214,22 @@ true Implement your custom character below. ```elixir +defmodule Archer do + defstruct [] +end +``` + +```elixir +defimpl Character, for: Archer do + def can_attack?(_character, {x1, y1}, {x2, y2}) do + # can move +/- 3 spaces along the x axis -> horizontal + # can move +/- 3 spaces along the y axis -> vertical + # horizontal # vertical + abs(x2 - x1) == 3 or abs(y2 - y1) == 3 + end +end +Character.can_attack?(%Archer{}, {4, 4}, {8, 8}) ``` ## Mark As Completed diff --git a/exercises/book_search.livemd b/exercises/book_search.livemd index a63beca18..9c76e8eaa 100644 --- a/exercises/book_search.livemd +++ b/exercises/book_search.livemd @@ -30,6 +30,7 @@ defmodule Book do iex> %Book{title: "My Book Title"} %Book{title: "My Book Title"} """ + defstruct [:title] @doc """ Search a list of Book structs. Search should match any book that includes the @@ -38,6 +39,7 @@ defmodule Book do ## Examples Include books that exactly match the search query. + # Map.get(map, :title) == query iex> book1 = %Book{title: "A"} iex> book2 = %Book{title: "B"} @@ -46,6 +48,8 @@ defmodule Book do [%Book{title: "A"}] Include books that partially match the search query. + # does the query match any letter of the title? + # use String.contains(book, query) iex> Book.search([%Book{title: "ABC"}], "A") [%Book{title: "ABC"}] @@ -54,15 +58,36 @@ defmodule Book do [%Book{title: "BAC"}] Search should be case insensitive. + # lowercase the input and title iex> Book.search([%Book{title: "ABC"}], "a") [%Book{title: "ABC"}] """ + + # def fuzzy_match(string, char) do + # mysplit = String.split(string, "", trim: true) + # Enum.filter(mysplit, fn element -> element == char end) && string + # end + def search(books, query) do + # books that match one letter + Enum.filter(books, fn book -> String.contains?(book, query) end) + + # books that exactly match + Enum.filter(books, fn book -> Map.get(book, :title) end) end end ``` +```elixir +book = "ABC" +query = "D" +String.contains?(book, query) + +test = %{mybook: "mytitle"} +Map.get(test, ) +``` + ## Mark As Completed diff --git a/exercises/caesar_cypher.livemd b/exercises/caesar_cypher.livemd index 91df9252d..2066ca8fc 100644 --- a/exercises/caesar_cypher.livemd +++ b/exercises/caesar_cypher.livemd @@ -82,13 +82,13 @@ defmodule CaesarCypher do ## Examples - iex> CaesarCypher.encode("abcdefghijklmnopqrstuvwxyz") - "bcdefghijklmnopqrstuvwxyza" + # iex> CaesarCypher.encode("abcdefghijklmnopqrstuvwxyz") + # "bcdefghijklmnopqrstuvwxyza" - Encoding should work on any string + # Encoding should work on any string - iex> CaesarCypher.encode("hello") - "ifmmp" + # iex> CaesarCypher.encode("hello") + # "ifmmp" """ def encode(string) do end @@ -99,14 +99,14 @@ defmodule CaesarCypher do ## Examples - iex> CaesarCypher.encode("abcdefghijklmnopqrstuvwxyz", 1) - "bcdefghijklmnopqrstuvwxyza" + # iex> CaesarCypher.encode("abcdefghijklmnopqrstuvwxyz", 1) + # "bcdefghijklmnopqrstuvwxyza" - iex> CaesarCypher.encode("abcdefghijklmnopqrstuvwxyz", 2) - "cdefghijklmnopqrstuvwxyzab" + # iex> CaesarCypher.encode("abcdefghijklmnopqrstuvwxyz", 2) + # "cdefghijklmnopqrstuvwxyzab" - iex> CaesarCypher.encode("abcdefghijklmnopqrstuvwxyz", 14) - "opqrstuvwxyzabcdefghijklmn" + # iex> CaesarCypher.encode("abcdefghijklmnopqrstuvwxyz", 14) + # "opqrstuvwxyzabcdefghijklmn" Encoding should work on any string. @@ -118,6 +118,25 @@ defmodule CaesarCypher do end ``` +```elixir +string = "abcdefghijklmnopqrstuvwxyz" +offset = 2 + +chars = String.to_charlist(string) + +Enum.map(chars, fn char -> char + 2 end) + +?z - offset + +# Enum.map(chars, fn char -> +# if char < 'z' - offset do +# 'z' +# else +# char + 2 +# end +# end) +``` + ## Mark As Completed diff --git a/exercises/counting_votes.livemd b/exercises/counting_votes.livemd index b7ca899b0..cb1e0c25e 100644 --- a/exercises/counting_votes.livemd +++ b/exercises/counting_votes.livemd @@ -80,6 +80,7 @@ defmodule Votes do 0 """ def count(votes, vote) do + Enum.count(Enum.filter(votes, fn item -> item == vote end)) end end ``` @@ -120,6 +121,10 @@ defmodule VoterTally do %{dog: 2, cat: 3, bird: 1} """ def tally(votes) do + dogs = Enum.count(Enum.filter(votes, fn item -> item == :dog end)) + cats = Enum.count(Enum.filter(votes, fn item -> item == :cat end)) + birds = Enum.count(Enum.filter(votes, fn item -> item == :bird end)) + %{dog: dogs, cat: cats, bird: birds} end end ``` diff --git a/exercises/custom_enum_with_reduce.livemd b/exercises/custom_enum_with_reduce.livemd index 108de363c..7bdee0bad 100644 --- a/exercises/custom_enum_with_reduce.livemd +++ b/exercises/custom_enum_with_reduce.livemd @@ -78,6 +78,11 @@ defmodule CustomEnum do [7, 6, 5, 4] """ def reverse(list) do + # put first element on head of new list + Enum.reduce(list, [], fn element, acc -> + # IO.inspect(binding()) + [element | acc] + end) end @doc """ @@ -92,6 +97,11 @@ defmodule CustomEnum do [true, true, true] """ def map(list, callback_function) do + # while list not empty apply fn to element + Enum.reduce(list, [], fn element, acc -> + [callback_function.(element) | acc] + end) + |> reverse() end @doc """ @@ -107,6 +117,15 @@ defmodule CustomEnum do ["2", "3"] """ def filter(list, callback_function) do + # add element to new list if callback_function(element) returns true + Enum.reduce(list, [], fn element, acc -> + if callback_function.(element) do + [element | acc] + else + acc + end + end) + |> reverse() end @doc """ @@ -117,10 +136,12 @@ defmodule CustomEnum do iex> CustomEnum.sum([1, 2, 3]) 6 - iex> CustomEnum.sum([1, 1, 1]) - 3 + # iex> CustomEnum.sum([1, 1, 1]) + # 3 """ def sum(list_of_integers) do + # add each int to accumulator and return accumulator + Enum.reduce(list_of_integers, 0, fn int, acc -> int + acc end) end @doc """ @@ -135,6 +156,8 @@ defmodule CustomEnum do "Hello, World!" """ def join(list_of_strings) do + # concat each string to acc string + Enum.reduce(list_of_strings, "", fn string, acc -> acc <> string end) end end ``` diff --git a/exercises/drill-patternmatching-replace-nils.livemd b/exercises/drill-patternmatching-replace-nils.livemd index 3ae0a4a58..e34dcb7a3 100644 --- a/exercises/drill-patternmatching-replace-nils.livemd +++ b/exercises/drill-patternmatching-replace-nils.livemd @@ -63,9 +63,39 @@ defmodule ReplaceNils do @doc """ replace nil values in the first list with values from the second list in the same position. + + iex> input1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + iex> input2 = [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil] + iex> ReplaceNils.replace(input1, input2) + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + + iex> input1 = [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil] + iex> input2 = [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j] + iex> ReplaceNils.replace(input1, input2) + [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j] + + iex> input1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + iex> input2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + iex> ReplaceNils.replace(input1, input2) + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + + iex> input1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + iex> input2 = [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j] + iex> ReplaceNils.replace(input1, input2) + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + + iex> input1 = [1, 2, 3, nil, nil, 6, 7, nil, 9, 10] + iex> input2 = [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j] + iex> ReplaceNils.replace(input1, input2) + [1, 2, 3, :d, :e, 6, 7, :h, 9, 10] + + """ def replace(input1, input2) do - nil + Enum.zip_with(input1, input2, fn + nil, y -> y + x, _ -> x + end) end end ``` diff --git a/exercises/email_validation.livemd b/exercises/email_validation.livemd index b885a48c8..002175697 100644 --- a/exercises/email_validation.livemd +++ b/exercises/email_validation.livemd @@ -82,17 +82,59 @@ defmodule Email do iex> Email.valid?("string.string") false - iex> Email.valid?("string@string") - false + # iex> Email.valid?("string@string") + # false - iex> Email.valid?("string@string.") - false + # iex> Email.valid?("string@string.") + # false """ def valid?(email) do + email_regex = ~r/ + \w+ # user + @ # @ + \w+ # host + [.] # . + \w+ # domain + /x + + Regex.match?(email_regex, email) end end ``` +```elixir +good_string = "mail@mail.com" +bad_string = "mail.com" + +email_regex = ~r/ + \w+ # user + @ # @ + \w+ # host + [.] # . + \w+ # domain + /x + +Regex.scan(email_regex, good_string) + +IO.puts(Regex.source(email_regex)) +``` + +```elixir +good_number = "1-123-123-1234" + +number_regex = ~r/ +\d{1} # country code +- # dash +\d{3} # area code +- # dash +\d{3} # exchange +- # dash +\d{4} # circuit number +/x + +Regex.scan(number_regex, good_number) +``` + ## Mark As Completed diff --git a/exercises/fibonacci.livemd b/exercises/fibonacci.livemd index 47b39202c..5453ed3a5 100644 --- a/exercises/fibonacci.livemd +++ b/exercises/fibonacci.livemd @@ -89,7 +89,11 @@ defmodule Fibonacci do iex> Fibonacci.of(20) 6765 """ + def of(0), do: 0 + def of(1), do: 1 + def of(n) do + of(n - 1) + of(n - 2) end end ``` diff --git a/exercises/file_drills.livemd b/exercises/file_drills.livemd index f2857625f..39840ef17 100644 --- a/exercises/file_drills.livemd +++ b/exercises/file_drills.livemd @@ -25,67 +25,72 @@ This set of drills is for the [File](../reading/file.livemd) module. Follow the Use [File.ls/1](https://hexdocs.pm/elixir/File.html#ls/1) to list all of the files/folders in the current path. ```elixir - +File.ls() ``` Use [File.ls/1](https://hexdocs.pm/elixir/File.html#ls/1) to list all of the files/folders in the parent directory of the current path. ```elixir - +File.ls("../") ``` Use [File.mkdir/1](https://hexdocs.pm/elixir/File.html#mkdir/1) to create a directory called `drills`. ```elixir - +File.cd("/Users/lotek/Desktop") +File.ls() +File.mkdir("drills") +File.ls() ``` Use [File.dir?/2](https://hexdocs.pm/elixir/File.html#dir?/2) to check that `drills` is a folder. ```elixir - +File.dir?("drills") ``` Use [File.write/3](https://hexdocs.pm/elixir/File.html#write/3) to create an empty file called `drills.txt`. ```elixir - +File.write("drills.txt", "") ``` Use [File.exists?/2](https://hexdocs.pm/elixir/File.html#exists?/2) to check that the `drills.txt` file exists. ```elixir - +File.exists?("drills.txt") ``` Use [File.dir?/2](https://hexdocs.pm/elixir/File.html#dir?/2) to check that `drills.txt` is not a folder. ```elixir - +File.dir?("drills.txt") ``` Use [File.write/3](https://hexdocs.pm/elixir/File.html#write/3) to create a filed called `hello.txt` with the content `"world"`. ```elixir - +File.write("hello.txt", "world") ``` Use [File.read/1](https://hexdocs.pm/elixir/File.html#read/1) to read the content of the `hello.txt` file. ```elixir - +File.read("hello.txt") ``` Use [File.write/3](https://hexdocs.pm/elixir/File.html#write/3) to create an empty file in the `drills` folder you previously created. ```elixir - +File.cd("drills") +File.ls() +File.write("empty.txt", "") ``` Use [File.write/3](https://hexdocs.pm/elixir/File.html#write/3) to create an `error/no_entity.txt` file that should return `{:error, :enoent}` because the `error` folder does not exist. ```elixir - +{:error, :enoent} = File.write("error/no_entity.txt", "") ``` Use [File.write/3](https://hexdocs.pm/elixir/File.html#write/3) to create a file `multi-line.txt` with a multi-line string. @@ -103,19 +108,29 @@ line 5 ``` ```elixir +multiline_string = """ +line 1 +line 2 +line 3 +line 4 +line 5 +""" +File.rm("multi-line.txt") +File.ls() +File.write("multi-line.txt", multiline_string) ``` Use [File.read/1](https://hexdocs.pm/elixir/File.html#read/1) to read `multi-line.txt`. ```elixir - +File.read("multi-line.txt") ``` Use [File.stream!/3](https://hexdocs.pm/elixir/File.html#stream!/3) to read each line of `multi-line.txt` and convert it to a list of lines using [Enum.to_list/1](https://hexdocs.pm/elixir/Enum.html#to_list/1). ```elixir - +File.stream!("multi-line.txt") |> Enum.to_list() ``` Use [File.stream!/3](https://hexdocs.pm/elixir/File.html#stream!/3) and [Stream.filter/2](https://hexdocs.pm/elixir/Stream.html#filter/2) to filter in lines from `multi-line.txt` that contain numbers less than or equal to `3`. @@ -133,7 +148,9 @@ line 3 ``` ```elixir +file = "multi-line.txt" +File.stream!(file) |> Stream.filter(fn elem -> elem.in() <= 3 end) |> Enum.to_list() ``` Use [File.open/2](https://hexdocs.pm/elixir/File.html#open/2), [IO.binread/2](https://hexdocs.pm/elixir/IO.html#binread/2), and [File.close/1](https://hexdocs.pm/elixir/File.html#close/1) to read the first line of `multi-line.txt`. Print the value. diff --git a/exercises/filter_values_by_type.livemd b/exercises/filter_values_by_type.livemd index 2b9025019..1092bfeb9 100644 --- a/exercises/filter_values_by_type.livemd +++ b/exercises/filter_values_by_type.livemd @@ -82,7 +82,10 @@ defmodule Filter do iex> Filter.integers([1, 2, %{}, {}, []]) [1, 2] """ + + # filter list using is_integer def integers(list) do + Enum.filter(list, fn element -> is_integer(element) end) end @doc """ @@ -94,6 +97,7 @@ defmodule Filter do [1.2, 3.2] """ def floats(list) do + Enum.filter(list, fn element -> is_float(element) end) end @doc """ @@ -105,6 +109,7 @@ defmodule Filter do [1, 2, 1.2, 3.2] """ def numbers(list) do + Enum.filter(list, fn element -> is_integer(element) or is_float(element) end) end @doc """ @@ -116,6 +121,7 @@ defmodule Filter do [:first_atom, :second_atom] """ def atoms(list) do + Enum.filter(list, fn element -> is_atom(element) end) end @doc """ @@ -127,6 +133,7 @@ defmodule Filter do [[1, 2], [4, 5, 6]] """ def lists(list) do + Enum.filter(list, fn element -> is_list(element) && element != [] end) end @doc """ @@ -138,6 +145,7 @@ defmodule Filter do [%{}, %{key: "value"}] """ def maps(list) do + Enum.filter(list, fn element -> is_map(element) end) end @doc """ @@ -149,6 +157,7 @@ defmodule Filter do [[], [key: "value"]] """ def keyword_lists(list) do + Enum.filter(list, fn element -> Keyword.keyword?(element) end) end end ``` diff --git a/exercises/fizzbuzz.livemd b/exercises/fizzbuzz.livemd index 179fe2c17..a1393a308 100644 --- a/exercises/fizzbuzz.livemd +++ b/exercises/fizzbuzz.livemd @@ -77,8 +77,18 @@ defmodule FizzBuzz do ["buzz", 11, "fizz", 13, 14, "fizzbuzz"] """ def run(range) do + Enum.map(range, fn int -> + cond do + rem(int, 15) == 0 -> "fizzbuzz" + rem(int, 3) == 0 -> "fizz" + rem(int, 5) == 0 -> "buzz" + true -> int + end + end) end end + +FizzBuzz.run(1..15) ``` ## Mark As Completed diff --git a/exercises/itinerary.livemd b/exercises/itinerary.livemd index ae7a980ca..396207755 100644 --- a/exercises/itinerary.livemd +++ b/exercises/itinerary.livemd @@ -58,10 +58,21 @@ defmodule Itinerary do """ def has_time?(start, finish, minutes) do + start = DateTime.to_unix(start) + finish = DateTime.to_unix(finish) + + available_time = finish - start + task_time = minutes * 60 + + task_time <= available_time end end ``` +```elixir +DateTime.utc_now() |> DateTime.to_unix() +``` + ## Mark As Completed diff --git a/exercises/lucas_numbers.livemd b/exercises/lucas_numbers.livemd index 658be16ab..b19d965f8 100644 --- a/exercises/lucas_numbers.livemd +++ b/exercises/lucas_numbers.livemd @@ -117,7 +117,11 @@ defmodule Lucas do iex> Lucas.number(20) 15127 """ + def number(0), do: 2 + def number(1), do: 1 + def number(n) do + number(n - 1) + number(n - 2) end @doc """ @@ -142,10 +146,16 @@ defmodule Lucas do """ def sequence(length) do + Enum.map(0..(length - 1), fn elem -> number(elem) end) end end ``` +```elixir +# [2, 1, 3, 4] +[] +``` + ## Mark As Completed diff --git a/exercises/math_with_guards.livemd b/exercises/math_with_guards.livemd index 901a3f2f8..4ffd85a57 100644 --- a/exercises/math_with_guards.livemd +++ b/exercises/math_with_guards.livemd @@ -122,7 +122,16 @@ defmodule Math do iex> Math.add(%{}, %{}) ** (FunctionClauseError) no function clause matching in Math.add/2 """ - def add(value1, value2) do + def add(value1, value2) when is_integer(value1) and is_integer(value2) do + value1 + value2 + end + + def add(value1, value2) when is_binary(value1) and is_binary(value2) do + value1 <> value2 + end + + def add(value1, value2) when is_list(value1) and is_list(value2) do + value1 ++ value2 end @doc """ @@ -161,12 +170,26 @@ defmodule Math do iex> Math.subtract(%{}, %{}) ** (FunctionClauseError) no function clause matching in Math.subtract/2 """ - def subtract(value1, value2) do + def subtract(value1, value2) when is_integer(value1) and is_integer(value2) do + value1 - value2 + end + + def subtract(value1, value2) when is_binary(value1) and is_binary(value2) do + (String.split(value1, "", trim: true) -- String.split(value2, "", trim: true)) + |> List.to_string() + end + + def subtract(value1, value2) when is_list(value1) and is_list(value2) do + value1 -- value2 end end ``` -## Mark As Completed +```elixir +string1 = String.split("abcd", "", trim: true) +string2 = String.split("abc", "", trim: true) +List.to_string(string1 -- string2) +``` diff --git a/exercises/math_with_protocols.livemd b/exercises/math_with_protocols.livemd index 68e4b771d..2ac0eb158 100644 --- a/exercises/math_with_protocols.livemd +++ b/exercises/math_with_protocols.livemd @@ -116,9 +116,9 @@ defprotocol Math do iex> Math.add(4, 4) 8 - Math.add([1, 2], [3, 4]) + iex> Math.add([1, 2], [3, 4]) [1, 2, 3, 4] - Math.add([1, 2, 3], [4, 5, 6]) + iex> Math.add([1, 2, 3], [4, 5, 6]) [1, 2, 3, 4, 5, 6] iex> Math.add("abc", "def") @@ -132,6 +132,7 @@ defprotocol Math do iex> Math.add({}, {}) ** (Protocol.UndefinedError) protocol Math not implemented for {} of type Tuple """ + def add(value1, value2) @doc """ @@ -162,10 +163,45 @@ defprotocol Math do """ def subtract(value1, value2) end + +defimpl Math, for: Integer do + def add(value1, value2) do + value1 + value2 + end + + def subtract(value1, value2) do + value1 - value2 + end +end + +defimpl Math, for: List do + def add(value1, value2) do + value1 ++ value2 + end + + def subtract(value1, value2) do + value1 -- value2 + end +end + +defimpl Math, for: BitString do + def add(value1, value2) do + value1 <> value2 + end + + def subtract(value1, value2) do + (String.graphemes(value1) -- String.graphemes(value2)) + |> List.to_string() + end +end ``` ## Mark As Completed +```elixir +String.graphemes("abc") +``` + ```elixir diff --git a/exercises/message_validation.livemd b/exercises/message_validation.livemd index bf26498b1..dddb82fdc 100644 --- a/exercises/message_validation.livemd +++ b/exercises/message_validation.livemd @@ -93,13 +93,13 @@ defmodule Message do iex> %Message{} %Message{body: nil} """ - defstruct [] + defstruct [:body] @doc """ Send messages between users. Returns a string of the message if provided valid input. - ## Examples + ## Examples iex> Message.send("hello!") "hello!" @@ -116,19 +116,31 @@ defmodule Message do iex> Message.send(123) ** (FunctionClauseError) no function clause matching in Message.send/1 + iex> Message.send(%{}) ** (FunctionClauseError) no function clause matching in Message.send/1 + iex> Message.send({}) ** (FunctionClauseError) no function clause matching in Message.send/1 + iex> Message.send(%Message{body: nil}) ** (FunctionClauseError) no function clause matching in Message.send/1 - + + iex> Message.send(%Message{body: {}}) ** (FunctionClauseError) no function clause matching in Message.send/1 + """ - def send(message) do + # sender sends message + def send(message) when is_binary(message) do + message + end + + # receiver sends back message body + def send(message) when is_binary(message.body) do + message.body end end ``` diff --git a/exercises/named_number_lists.livemd b/exercises/named_number_lists.livemd index 7b1f06cba..ac6e70d07 100644 --- a/exercises/named_number_lists.livemd +++ b/exercises/named_number_lists.livemd @@ -75,7 +75,22 @@ flowchart Enter your solution below. ```elixir - +rando = Enum.map(1..10, fn _ -> Enum.random(0..9) end) + +Enum.map(rando, fn int -> + case int do + 0 -> "zero" + 1 -> "one" + 2 -> "two" + 3 -> "three" + 4 -> "four" + 5 -> "five" + 6 -> "six" + 7 -> "seven" + 8 -> "eight" + 9 -> "nine" + end +end) ``` ## Mark As Completed diff --git a/exercises/naming_numbers.livemd b/exercises/naming_numbers.livemd index df121b16f..24319112b 100644 --- a/exercises/naming_numbers.livemd +++ b/exercises/naming_numbers.livemd @@ -72,7 +72,22 @@ naming_numbers.(1) Enter your solution below. ```elixir +naming_numbers = fn integer -> + case integer do + 0 -> "zero" + 1 -> "one" + 2 -> "two" + 3 -> "three" + 4 -> "four" + 5 -> "five" + 6 -> "six" + 7 -> "seven" + 8 -> "eight" + 9 -> "nine" + end +end +naming_numbers.(1) ``` ## Numbering Names @@ -169,7 +184,22 @@ flowchart ```elixir +numbering_names = fn int_str -> + case String.downcase(int_str) do + "zero" -> 0 + "one" -> 1 + "two" -> 2 + "three" -> 3 + "four" -> 4 + "five" -> 5 + "six" -> 6 + "seven" -> 7 + "eight" -> 8 + "nine" -> 9 + end +end +numbering_names.("Nine") ``` ## Mark As Completed diff --git a/exercises/number_finder.livemd b/exercises/number_finder.livemd index 8a9a5a859..05f9cb9d0 100644 --- a/exercises/number_finder.livemd +++ b/exercises/number_finder.livemd @@ -37,12 +37,21 @@ defmodule NumberFinder do iex> NumberFinder.smallest([2, 3, 1]) 1 + iex> NumberFinder.smallest([2, 2, 3, 4]) 2 + iex> NumberFinder.smallest([2, 2, 3, 4, 10, 20, -3]) -3 """ def smallest(number_list) do + Enum.reduce(number_list, fn elem, acc -> + if acc < elem do + acc + else + elem + end + end) end @doc """ @@ -52,12 +61,21 @@ defmodule NumberFinder do iex> NumberFinder.largest([2, 3, 1]) 3 + iex> NumberFinder.largest([2, 2, 3, 4, 4]) 4 + iex> NumberFinder.largest([2, 2, 3, 4, 10, 20, -3]) 20 """ def largest(number_list) do + Enum.reduce(number_list, fn elem, acc -> + if acc > elem do + acc + else + elem + end + end) end end ``` diff --git a/exercises/palindrome.livemd b/exercises/palindrome.livemd index a6137c0ba..7a3b1c845 100644 --- a/exercises/palindrome.livemd +++ b/exercises/palindrome.livemd @@ -70,6 +70,7 @@ defmodule Palindrome do false """ def palindrome?(string) do + string == String.reverse(string) end end ``` diff --git a/exercises/rock_paper_scissors.livemd b/exercises/rock_paper_scissors.livemd index 0cfd2820c..7b8073b0d 100644 --- a/exercises/rock_paper_scissors.livemd +++ b/exercises/rock_paper_scissors.livemd @@ -54,7 +54,15 @@ Then, return the winning choice of either `:rock`, `:paper`, or `:scissors` that Enter your solution below. ```elixir +player_choice = Enum.random([:rock, :paper, :scissors]) + +IO.puts(player_choice) +case player_choice do + :rock -> :paper + :paper -> :scissors + :scissors -> :rock +end ``` ## Create Two Player Rock Paper Scissors @@ -107,7 +115,21 @@ Bind a `player1_choice` and `player2_choice` variable to `:rock`, `:paper`, or ` Enter your solution below. ```elixir - +player1 = Enum.random([:rock, :paper, :scissors]) +IO.inspect(player1: player1) + +player2 = Enum.random([:rock, :paper, :scissors]) +IO.inspect(player2: player2) + +case {player1, player2} do + {:rock, :scissors} -> "Player 1 Wins!" + {:paper, :rock} -> "Player 1 Wins!" + {:scissors, :paper} -> "Player 1 Wins!" + {:rock, :paper} -> "Player 2 Wins!" + {:paper, :scissors} -> "Player 2 Wins!" + {:scissors, :rock} -> "Player 2 Wins!" + {same, same} -> "Draw" +end ``` ## Mark As Completed diff --git a/exercises/rock_paper_scissors_lizard_spock.livemd b/exercises/rock_paper_scissors_lizard_spock.livemd index 400a7af02..e924cdd3f 100644 --- a/exercises/rock_paper_scissors_lizard_spock.livemd +++ b/exercises/rock_paper_scissors_lizard_spock.livemd @@ -83,6 +83,17 @@ defmodule RockPaperScissorsLizardSpock do false """ def beats?(guess1, guess2) do + {guess1, guess2} in [ + {:rock, :scissors}, + {:rock, :lizard}, + {:paper, :rock}, + {:paper, :spock}, + {:scissors, :paper}, + {:scissors, :lizards}, + {:lizard, :paper}, + {:lizard, :spock}, + {:spock, :scissors} + ] end @doc """ @@ -99,9 +110,20 @@ defmodule RockPaperScissorsLizardSpock do iex> RockPaperScissorsLizardSpock.play(:lizard, :lizard) "Player 2 Wins!" """ + def play(player1, player2) do + cond do + beats?(player1, player2) -> "Player 1 Wins!" + not beats?(player1, player2) -> "Player 2 Wins!" + end end end + +RockPaperScissorsLizardSpock.play(:rock, :paper) +``` + +```elixir + ``` ## Mark As Completed diff --git a/exercises/rpg_dialogue.livemd b/exercises/rpg_dialogue.livemd index dd17f3caf..7006b4ffd 100644 --- a/exercises/rpg_dialogue.livemd +++ b/exercises/rpg_dialogue.livemd @@ -82,7 +82,9 @@ defmodule Character do iex> %Character{name: "Frodo"} ** (ArgumentError) the following keys must also be given when building struct Character: [:name] """ - defstruct [] + @enforced_key [:name] + + defstruct @enforced_key ++ [:class, :weapon] @doc """ Introduce the character by name. @@ -95,7 +97,8 @@ defmodule Character do iex> Character.introduce(%Character{name: "Aragorn"}) "My name is Aragorn." """ - def introduce(character) do + def introduce(char) do + "My name is #{char.name}." end @doc """ @@ -109,7 +112,8 @@ defmodule Character do iex> Character.attack(%Character{name: "Aragorn", weapon: "sword"}) "I attack with my sword!" """ - def attack(character) do + def attack(char) do + "I attack with my #{char.weapon}!" end @doc """ @@ -123,7 +127,8 @@ defmodule Character do iex> Character.class(%Character{name: "Aragorn", class: "ranger"}) "I am a ranger." """ - def class(character) do + def class(char) do + "I am a #{char.class}." end @doc """ @@ -137,9 +142,14 @@ defmodule Character do iex> Character.war_cry(%Character{name: "Aragorn", class: "ranger"}) "My name is Aragorn and I am a ranger!" """ - def war_cry(character) do + def war_cry(char) do + "My name is #{char.name} and I am a #{char.class}!" end + # def war_cry2(name, class) do + # "My name is #{name} and I am a #{class}" + # end + @doc """ Declare that one character has defeated another. @@ -151,9 +161,31 @@ defmodule Character do iex> Character.defeat(%Character{name: "Aragorn"}, %Character{name: "Gimli", class: "warrior"}) "My name is Aragorn and I have defeated the warrior Gimli!" """ - def defeat(character1, character2) do + def defeat(char1, char2) do + "My name is #{char1.name} and I have defeated the #{char2.class} #{char2.name}!" end end + +# defmodule Test do +# import Character + +# def test do +# aragorn = %Character{name: "Aragorn", class: "ranger", weapon: "sword"} +# gandalf = %Character{name: "Gandalf", class: "wizard", weapon: "staff"} +# Character.introduce(aragorn) +# Character.attack(aragorn) +# Character.class(aragorn) +# Character.war_cry(aragorn) +# Character.war_cry2(aragorn.name, aragorn.class) +# Character.defeat(aragorn, gandalf) +# end +# end + +# Test.test +``` + +```elixir + ``` ### Bonus: Character Instances diff --git a/exercises/save_game.livemd b/exercises/save_game.livemd index 3c0c5c5e5..bcce80873 100644 --- a/exercises/save_game.livemd +++ b/exercises/save_game.livemd @@ -58,12 +58,14 @@ defmodule Game do Save an elixir term into a given file name. """ def save(data, filename) do + File.write!(filename, :erlang.term_to_binary(data)) end @doc """ Retrieve an elixir term from a given file name. """ def load(filename) do + File.read!(filename) |> :erlang.binary_to_term() end end ``` diff --git a/exercises/tic-tac-toe.livemd b/exercises/tic-tac-toe.livemd index 08c12950f..bafb9544f 100644 --- a/exercises/tic-tac-toe.livemd +++ b/exercises/tic-tac-toe.livemd @@ -153,7 +153,13 @@ defmodule TicTacToe do iex> TicTacToe.at(board, {2, 2}) "C" """ + def at(board, coordinate) do + {x, y} = coordinate + + Enum.reverse(board) + |> Enum.at(y) + |> Enum.at(x) end @doc """ @@ -177,6 +183,15 @@ defmodule TicTacToe do [[nil, "X", "O"], [nil, "X", "O"],[nil, nil, "X"]] """ def fill(board, coordinate, symbol) do + {x, y} = coordinate + + row_index = 2 - y + + row = Enum.at(board, row_index) + + new_row = List.replace_at(row, x, symbol) + + List.replace_at(board, row_index, new_row) end end ``` diff --git a/exercises/time_converting.livemd b/exercises/time_converting.livemd index 5346dbbf2..578aeae68 100644 --- a/exercises/time_converting.livemd +++ b/exercises/time_converting.livemd @@ -74,6 +74,12 @@ defmodule TimeConverter do """ def to_seconds(amount, unit) do + case unit do + :seconds -> amount + :minutes -> amount * 60 + :hours -> amount * 3600 + :days -> amount * 86400 + end end @doc """ @@ -82,8 +88,8 @@ defmodule TimeConverter do ## Examples - iex> TimeConverter.from_seconds(1, :seconds) - 1.0 + iex> TimeConverter.from_seconds(2, :seconds) + 2.0 iex> TimeConverter.from_seconds(60, :minutes) 1.0 @@ -96,6 +102,12 @@ defmodule TimeConverter do """ def from_seconds(amount, unit) do + case unit do + :seconds -> amount / 1.0 + :minutes -> amount / 60 + :hours -> amount / 3600 + :days -> amount / 86400 + end end end ``` diff --git a/exercises/timeline.livemd b/exercises/timeline.livemd index 5bb45c981..6cafbd278 100644 --- a/exercises/timeline.livemd +++ b/exercises/timeline.livemd @@ -96,6 +96,14 @@ defmodule Timeline do [9, 12, 2] """ def from_dates(dates) do + # chunk the date list into pairs with offset = 1 + # map over the chunked pairs with Date.diff + + pairs = Enum.chunk_every(dates, 2, 1, :discard) + + Enum.map(pairs, fn [date1, date2] -> + Date.diff(date2, date1) + end) end @doc """ @@ -113,11 +121,31 @@ defmodule Timeline do iex> Timeline.from_strings(["2020-01-01", "2020-01-10", "2020-01-22", "2020-01-24"]) [9, 12, 2] """ + + def make_date_from_string(string) do + [year, month, day] = String.split(string, "-", trim: true) + Date.new!(String.to_integer(year), String.to_integer(month), String.to_integer(day)) + end + def from_strings(date_strings) do + # convert list of strings to new list of dates + # call from_dates with new list of dates + + new_list = Enum.map(date_strings, fn string -> make_date_from_string(string) end) + from_dates(new_list) end end ``` +```elixir +test_string = ["2020-01-01", "2020-01-10", "2020-01-22", "2020-01-24"] + +Enum.map(test_string, fn string -> + [year, month, day] = String.split(string, "-", trim: true) + Date.new!(String.to_integer(year), String.to_integer(month), String.to_integer(day)) +end) +``` + ## Mark As Completed diff --git a/exercises/treasure_matching.livemd b/exercises/treasure_matching.livemd index 8995e1bf2..854e2a4aa 100644 --- a/exercises/treasure_matching.livemd +++ b/exercises/treasure_matching.livemd @@ -27,79 +27,98 @@ jewel Use pattern matching to bind a `jewel` variable to the `"jewel"` string. ```elixir -[1, 2, 3, "jewel"] +[_, _, _, jewel] = [1, 2, 3, "jewel"] +jewel ``` ```elixir -%{key1: "value", key2: "jewel"} +%{key1: value, key2: jewel} = %{key1: "value", key2: "jewel"} +jewel ``` ```elixir -%{1 => "jewel"} +%{1 => jewel} = %{1 => "jewel"} +jewel ``` ```elixir -%{%{key: [1, 2, 3, 4, 5, {}]} => "jewel"} +%{%{key: [1, 2, 3, 4, 5, {}]} => jewel} = %{%{key: [1, 2, 3, 4, 5, {}]} => "jewel"} +jewel ``` ```elixir -%{north: %{south: %{west: %{east: "jewel"}}}} +%{north: %{south: %{west: %{east: jewel}}}} = %{north: %{south: %{west: %{east: "jewel"}}}} +jewel ``` ```elixir -[2, "jewel"] +[_, jewel] = [2, "jewel"] +jewel ``` ```elixir -["jewel", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] +[jewel | tail] = ["jewel", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] +jewel ``` ```elixir -[1, "jewel", 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] +[_, jewel | tail] = [1, "jewel", 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] +jewel ``` ```elixir -[1, 2, "jewel", 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] +[_, _, jewel | tail] = [1, 2, "jewel", 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] +jewel ``` ```elixir -[[], [1, [2, "jewel"]]] +[_, [_, [_ | jewel]]] = [[], [1, [2, "jewel"]]] +jewel ``` ```elixir -"here is the jewel" +"here is the " <> jewel = "here is the jewel" +jewel ``` ```elixir -{"jewel"} +{jewel} = {"jewel"} +jewel ``` ```elixir -{"jewel", 1} +{jewel, _} = {"jewel", 1} +jewel ``` ```elixir -{1, 2, "jewel"} +{_, _, jewel} = {1, 2, "jewel"} +jewel ``` ```elixir -["jewel"] ++ Enum.to_list(1..100) +[jewel | tail] = ["jewel"] ++ Enum.to_list(1..100) +jewel ``` ```elixir -[key: "jewel"] +[key: jewel] = [key: "jewel"] +jewel ``` ```elixir -[south: "jewel", east: {1, 2}] +[{:south, jewel} | tail] = [south: "jewel", east: {1, 2}, north: "two"] +jewel ``` ```elixir -Enum.map(1..4, fn each -> (each == 2 && "jewel") || each end) +[_, jewel | tail] = Enum.map(1..4, fn each -> (each == 2 && "jewel") || each end) +jewel ``` ```elixir -Enum.map(1..4, &((&1 > 3 && "jewel") || &1)) +[_, _, _, jewel] = Enum.map(1..4, &((&1 > 3 && "jewel") || &1)) +jewel ``` ## Mark As Completed diff --git a/exercises/typespec_drills.livemd b/exercises/typespec_drills.livemd index 3ed091780..faaa46eee 100644 --- a/exercises/typespec_drills.livemd +++ b/exercises/typespec_drills.livemd @@ -157,72 +157,89 @@ end ```elixir defmodule FunctionSpecs do + @spec do_nothing :: nil def do_nothing do nil end + @spec accept_and_return_anything(any()) :: any() def accept_and_return_anything(anything) do anything end + @spec double(float()) :: float() def double(float) when is_float(float) do float * 2.0 end + @spec double(integer()) :: integer() def double(integer) when is_integer(integer) do integer * 2 end + @spec double(number()) :: number() def double(number) do number * 2 end + @spec add(integer(), integer()) :: integer() def add(integer1, integer2) do integer1 + integer2 end + @spec multiply(integer(), integer()) :: integer() def multiply(integer1, integer2) do integer1 * integer2 end + @spec divide(integer(), integer()) :: float() def divide(integer1, integer2) do integer1 / integer2 end + @spec rounded_divide(integer(), integer()) :: integer() def rounded_divide(integer1, integer2) do div(integer1, integer2) end + @spec concat(String.t(), String.t()) :: String.t() def concat(string1, string2) do string1 <> string2 end + @spec to_string(integer()) :: String.t() def to_string(integer) do Integer.to_string(integer) end + @spec merge(map(), map()) :: map() def merge(map1, map2) do Map.merge(map1, map2) end + @spec get_or_empty(Keyword.t(), atom()) :: any() def get_or_empty(keyword_list, atom_key) do Keyword.get(keyword_list, atom_key, "") end + @spec split_and_lowercase(String.t()) :: [String.t()] def split_and_lowercase(string) do string |> String.downcase() |> String.split("", trim: true) end + @spec string_to_int(String.t()) :: integer() def string_to_int(string) do String.to_integer(string) end + @spec integers_to_strings([integer()]) :: [String.t()] def integers_to_strings(integers) do Enum.map(integers, fn int -> Integer.to_string(int) end) end + @spec one_to_two(1) :: 2 def one_to_two(1) do 2 end @@ -254,13 +271,13 @@ end ```elixir defmodule CustomTypes do # a string or number - @type unparsed_number + @type unparsed_number :: String.t() | number() # a list of strings - @type strings + @type strings :: [String.t()] # a map with :title (string) and :content (string) keys. - @type book + @type book :: %{title: String.t(), content: String.t()} # A map with :name (string) and `:books` (a list of books) keys. - @type author + @type author :: %{name: String.t(), books: [book()]} end ``` diff --git a/exercises/weighted_voting.livemd b/exercises/weighted_voting.livemd index 96eb35039..166bb852c 100644 --- a/exercises/weighted_voting.livemd +++ b/exercises/weighted_voting.livemd @@ -82,12 +82,21 @@ defmodule WeightedVoting do iex> WeightedVoting.count([dogs: 20, dogs: 10], :dogs) 30 + iex> WeightedVoting.count([cats: 10, dogs: 20, dogs: 30], :dogs) 50 + iex> WeightedVoting.count([cats: 10, dogs: 20, dogs: 10, cats: 30], :cats) 40 """ def count(votes, vote_to_count) do + Enum.reduce(votes, 0, fn {key, value}, acc -> + if key == vote_to_count do + acc + value + else + acc + end + end) end @doc """ @@ -100,16 +109,35 @@ defmodule WeightedVoting do iex> WeightedVoting.tally([dogs: 20, dogs: 10]) [dogs: 30] + iex> WeightedVoting.tally([cats: 10, dogs: 20, dogs: 10]) [cats: 10, dogs: 30] + iex> WeightedVoting.tally([cats: 10, dogs: 20, cats: 20, dogs: 10, birds: 20]) [birds: 20, cats: 30, dogs: 30] """ def tally(votes) do + Enum.reduce(votes, [], fn {animal, value}, acc -> + Keyword.update(acc, animal, value, fn existing_value -> + value + existing_value + end) + end) + |> Enum.sort() end end ``` +```elixir +votes = [cats: 10, dogs: 20, cats: 20, dogs: 10, birds: 20] +vote_to_count = :birds + +def count(votes, vote_to_count) do + Enum.reduce(votes, fn acc, vote_to_count -> + IO.inspect(binding()) + end) +end +``` + ### Bonus: Tally Map Create a `WeightedVoting.tally_map/1` function which returns a map instead of a keyword list. diff --git a/exercises/with_points.livemd b/exercises/with_points.livemd index a6cf47a66..86a33af07 100644 --- a/exercises/with_points.livemd +++ b/exercises/with_points.livemd @@ -73,6 +73,13 @@ end Enter your solution below. +```elixir +%{team1_name: team1, team2_name: team2} +%{round1: %{team1: team1r1, team2: team2r1}} +%{round2: %{team1: team1r2, team2: team2r2}} +%{round3: %{team1: team1r3, team2: team2r3}} +``` + ```elixir defmodule Points do @doc """ @@ -96,15 +103,15 @@ defmodule Points do """ def tally(game) do with %{team1_name: team1, team2_name: team2} <- game, - %{round1: %{team1: t1r1, team2: t2r1}} <- game, - %{round2: %{team1: t1r2, team2: t2r2}} <- game, - %{round3: %{team1: t1r3, team2: t2r3}} <- game do + %{round1: %{team1: team1r1, team2: team2r1}} <- game, + %{round2: %{team1: team1r2, team2: team2r2}} <- game, + %{round3: %{team1: team1r3, team2: team2r3}} <- game do %{} - |> Map.put(team1, t1r1 + t1r2 + t1r3) - |> Map.put(team2, t2r1 + t2r2 + t2r3) + # IO.inspect(binding()) + |> Map.put(team1, team1r1 + team1r2 + team1r3) + |> Map.put(team2, team2r1 + team2r2 + team2r3) else - error -> - {:error, :invalid} + _error -> {:error, :invalid} end end end diff --git a/progress.json b/progress.json index c298c1f19..8dc084dcf 100644 --- a/progress.json +++ b/progress.json @@ -9,17 +9,17 @@ "mazes_exercise": false, "rollable_expressions_exercise": false, "modules_reading": false, - "file_reading": false, + "file_reading": true, "agents_and_ets_reading": false, "protocols_reading": false, "games_score_tracker_exercise": false, - "habit_tracker_exercise": false, + "habit_tracker_exercise": true, "reduce_reading": false, "code_editors_reading": false, "exdoc_reading": false, "process_drills_exercise": false, "saferange_exercise": false, - "time_converting_exercise": false, + "time_converting_exercise": true, "pokemon_server_exercise": false, "strings_reading": false, "counting_votes_exercise": false, @@ -43,28 +43,28 @@ "pascals_triangle_exercise": false, "book_search_book_content_reading": false, "portfolio_exercise": false, - "non_enumerables_reading": false, + "non_enumerables_reading": true, "control_flow_reading": false, "lists_vs_tuples_reading": false, "dominoes_exercise": false, "command_line_family_tree_exercise": false, "phoenix_and_ecto_reading": false, - "number_finder_exercise": false, + "number_finder_exercise": true, "pic_chat_image_upload_reading": false, - "timeline_exercise": false, + "timeline_exercise": true, "newsletter_reading": false, "advanced_pattern_matching_reading": false, - "games_guessing_game_exercise": false, + "games_guessing_game_exercise": true, "math_with_guards_exercise": false, "pokemon_api_exercise": false, "file_search_exercise": false, - "animal_generator_exercise": false, + "animal_generator_exercise": true, "group_project_blog_exercise": false, "treasure_matching_exercise": false, "github_engineering_journal_exercise": false, "mailbox_server_exercise": false, "blog_posts_exercise": false, - "git_reading": false, + "git_reading": true, "named_number_lists_exercise": false, "big_o_notation_reading": false, "battle_map_exercise": false, @@ -77,7 +77,7 @@ "caesar_cypher_exercise": false, "booleans_reading": false, "blog_comments_exercise": false, - "anagram_exercise": false, + "anagram_exercise": true, "lazy_product_filters_exercise": false, "file_system_todo_app_exercise": false, "phoenix_1.7_reading": false, @@ -86,7 +86,7 @@ "github_collab_exercise": false, "web_servers_reading": false, "book_search_deployment_reading": false, - "tic-tac-toe_exercise": false, + "tic-tac-toe_exercise": true, "games_supervised_score_tracker_exercise": false, "benchmarking_reading": false, "processes_reading": false, @@ -102,7 +102,7 @@ "rdbms_reading": false, "fun_formulas_exercise": false, "rpg_dialogue_exercise": false, - "palindrome_exercise": false, + "palindrome_exercise": true, "comprehensions_reading": false, "comments_reading": false, "rock_paper_scissors_exercise": false, @@ -112,13 +112,13 @@ "blog_seeding_exercise": false, "custom_enum_with_recursion_exercise": false, "drill-patternmatching-replace-nils_exercise": false, - "games_rock_paper_scissors_exercise": false, + "games_rock_paper_scissors_exercise": true, "blog_migration_exercise": false, "inventory_management_exercise": false, "iex_reading": false, "phone_number_parsing_exercise": false, "maps_reading": false, - "exunit_reading": false, + "exunit_reading": true, "keyword_lists_reading": false, "command_line_reading": false, "stack_exercise": false, @@ -129,7 +129,7 @@ "naming_numbers_exercise": false, "deployment_exercise": false, "typespecs_reading": false, - "card_counting_exercise": false, + "card_counting_exercise": true, "math_with_protocols_exercise": false, "stack_server_exercise": false, "pokemon_battle_exercise": false, @@ -141,11 +141,11 @@ "blog_content_exercise": false, "math_module_testing_exercise": false, "phoenix_authentication_reading": false, - "games_setup_exercise": false, + "games_setup_exercise": true, "task_drills_exercise": false, "monster_spawner_exercise": false, "metaprogramming_reading": false, - "start_here_reading": false, + "start_here_reading": true, "games_supervisor_setup_exercise": false, "pic_chat_pub_sub_reading": false, "lists_reading": false, @@ -153,18 +153,18 @@ "functions_reading": false, "spoonacular_recipe_api_exercise": false, "book_changeset_exercise": false, - "weighted_voting_exercise": false, + "weighted_voting_exercise": true, "supervisors_reading": false, - "save_game_exercise": false, + "save_game_exercise": true, "document_tools_exercise": false, "factorial_exercise": false, - "livebook_reading": false, - "filter_values_by_type_exercise": false, + "livebook_reading": true, + "filter_values_by_type_exercise": true, "book_search_exercise": false, "guards_reading": false, "sql_drills_exercise": false, "maps_mapsets_keyword_lists_reading": false, - "lucas_numbers_exercise": false, + "lucas_numbers_exercise": true, "mapset_product_filters_exercise": false, "consumable_protocol_exercise": false, "task_supervisor_reading": false, @@ -180,13 +180,13 @@ "with_points_exercise": false, "itinerary_exercise": false, "apis_reading": false, - "built-in_modules_reading": false, + "built-in_modules_reading": true, "rps_pattern_matching_exercise": false, "arithmetic_reading": false, "rps_guards_exercise": false, "book_search_tags_reading": false, "email_validation_exercise": false, - "custom_enum_with_reduce_exercise": false, + "custom_enum_with_reduce_exercise": true, "blog_comment_form_exercise": false, "doctests_reading": false, "pic_chat_infinite_scroll_reading": false, @@ -202,7 +202,7 @@ "recursion_reading": false, "in-memory_todo_list_exercise": false, "capstone_project_guide_reading": false, - "fibonacci_exercise": false, + "fibonacci_exercise": true, "typespec_drills_exercise": false, "custom_assertions_exercise": false, "atoms_reading": false diff --git a/reading/built-in_modules.livemd b/reading/built-in_modules.livemd index 55aeaa455..d574b8f19 100644 --- a/reading/built-in_modules.livemd +++ b/reading/built-in_modules.livemd @@ -108,6 +108,7 @@ Use [Kernel.elem/2](https://hexdocs.pm/elixir/Kernel.html#elem/2) to retrieve `1 ```elixir tuple = {0, 4, 1, 100, 5, 7} +elem(tuple, 3) ``` ## Checking Types @@ -149,31 +150,31 @@ is_atom(:example) ``` ```elixir -%{} +is_map(%{}) ``` ```elixir -{} +is_map({}) ``` ```elixir -[] +is_list([]) ``` ```elixir -true +is_boolean(true) ``` ```elixir -1.0 +is_float(1.0) ``` ```elixir -1 +is_integer(1) ``` ```elixir -"" +is_binary("") ``` The [Kernel](https://hexdocs.pm/elixir/Kernel.html) is reasonably large. Remember, our goal is not to memorize every function but to develop familiarity with repeated practice. @@ -213,8 +214,10 @@ Created a `capped_seconds` variable that uses the value of `seconds` and cannot Enter your solution below. if `seconds` is less than `0` `capped_seconds` should be `0`. If `seconds` is greater than `59`, then `capped_seconds` should be `59`. ```elixir -seconds = 60 -capped_seconds = nil +seconds = 20 +# min(seconds, 59) +# max(seconds, 0) +capped_seconds = max(min(seconds, 59), 0) ``` ## Safe Inspection @@ -264,7 +267,8 @@ map = %{} list = [1, 2, 3] tuple = {1, 2, 3} -"" +# "" +inspect(tuple) ``` ## The Integer Module @@ -345,7 +349,7 @@ Use the [Integer.gcd/2](https://hexdocs.pm/elixir/Integer.html#gcd/2) function t positive integer that divides both 10 and 15 evenly, so the result should be `5`. ```elixir - +Integer.gcd(10, 15) ``` ## The String Module @@ -427,7 +431,7 @@ Use the [String.at/2](https://hexdocs.pm/elixir/String.html#at/2) function to ge ```elixir -"hello" +String.at("hello", 2) ``` Use the [String.at/2](https://hexdocs.pm/elixir/String.html#at/2) function to retrieve the letter `"o"` in `"hello"` @@ -610,7 +614,7 @@ Use [List.delete_at/2](https://hexdocs.pm/elixir/List.html#delete_at/2) to remov ```elixir -[2, 1, 3] +List.delete_at([2, 1, 3], 0) ``` Use [List.flatten/1](https://hexdocs.pm/elixir/List.html#flatten/1) to flatten the following list into `[1, 2, 3, 4, 5, 6, 7, 8, 9]` @@ -626,7 +630,7 @@ Use [List.flatten/1](https://hexdocs.pm/elixir/List.html#flatten/1) to flatten t ```elixir -[1, 2, [3, 4, 5], 6, [7, [8, [9]]]] +List.flatten([1, 2, [3, 4, 5], 6, [7, [8, [9]]]]) ``` Use [List.insert_at/3](https://hexdocs.pm/elixir/List.html#insert_at/3) to insert `2` into the following list to make `[1, 2, 3]`. @@ -642,7 +646,7 @@ Use [List.insert_at/3](https://hexdocs.pm/elixir/List.html#insert_at/3) to inser ```elixir -[1, 3] +List.insert_at([1, 3], 1, 2) ``` Use [List.last/2](https://hexdocs.pm/elixir/List.html#last/2) to retrieve the last element `10000` in a list from `1` to `10000`. @@ -664,7 +668,7 @@ Use [List.last/2](https://hexdocs.pm/elixir/List.html#last/2) to retrieve the la ```elixir -Enum.to_list(1..10000) +List.last(Enum.to_list(1..10000)) ``` Use [List.update_at/3](https://hexdocs.pm/elixir/List.html#update_at/3) to subtract `2` from `4` in the following list to make `[1, 2, 3]`. @@ -680,7 +684,7 @@ Use [List.update_at/3](https://hexdocs.pm/elixir/List.html#update_at/3) to subtr ```elixir -[1, 4, 3] +List.update_at([1, 4, 3], 1, &(&1 - 2)) ``` Use [List.zip/1](https://hexdocs.pm/elixir/List.html#zip/1) to combine these two lists to make `[{"a", 1}, {"b", 2}, {"c", 3}]`. @@ -701,6 +705,7 @@ Use [List.zip/1](https://hexdocs.pm/elixir/List.html#zip/1) to combine these two ```elixir letters = ["a", "b", "c"] numbers = [1, 2, 3] +List.zip([letters, numbers]) ``` ## The Map Module @@ -756,7 +761,7 @@ Use [Map.get/3](https://hexdocs.pm/elixir/Map.html#get/3) to retrieve the `"worl ```elixir -%{hello: "world"} +Map.get(%{hello: "world"}, :hello) ``` Use [Map.put/3](https://hexdocs.pm/elixir/Map.html#put/3) to add the key `:two` with the value `2` to the following map. @@ -772,7 +777,7 @@ Use [Map.put/3](https://hexdocs.pm/elixir/Map.html#put/3) to add the key `:two` ```elixir -%{one: 1} +Map.put(%{one: 1}, :two, 2) ``` Use [Map.keys/1](https://hexdocs.pm/elixir/Map.html#keys/1) to retrieve the keys for the following map. @@ -788,7 +793,7 @@ Use [Map.keys/1](https://hexdocs.pm/elixir/Map.html#keys/1) to retrieve the keys ```elixir -%{key1: 1, key2: 2, key3: 3} +Map.keys(%{key1: 1, key2: 2, key3: 3}) ``` Use [Map.delete/2](https://hexdocs.pm/elixir/Map.html#delete/2) to remove `:key1` from the following map. @@ -804,7 +809,7 @@ Use [Map.delete/2](https://hexdocs.pm/elixir/Map.html#delete/2) to remove `:key1 ```elixir -%{key1: 1, key2: 2, key3: 3} +Map.delete(%{key1: 1, key2: 2, key3: 3}, :key1) ``` Use [Map.merge/2](https://hexdocs.pm/elixir/Map.html#merge/2) to combine `%{one: 1}` and `%{two: 2}`. @@ -820,7 +825,7 @@ Use [Map.merge/2](https://hexdocs.pm/elixir/Map.html#merge/2) to combine `%{one: ```elixir - +Map.merge(%{one: 1}, %{two: 2}) ``` Use [Map.update/4](https://hexdocs.pm/elixir/Map.html#update/4) or [Map.update!/3](https://hexdocs.pm/elixir/Map.html#update!/3) to update the `:count` key in this map to be `5` plus the existing value. @@ -836,7 +841,7 @@ Use [Map.update/4](https://hexdocs.pm/elixir/Map.html#update/4) or [Map.update!/ ```elixir -%{count: 10} +Map.update(%{count: 10}, :count, 10, &(&1 + 5)) ``` Use [Map.values/1](https://hexdocs.pm/elixir/Map.html#values/1) to retrieve the values `[1, 2, 3]` in the following map. @@ -852,7 +857,7 @@ Use [Map.values/1](https://hexdocs.pm/elixir/Map.html#values/1) to retrieve the ```elixir -%{key1: 1, key2: 2, key3: 3} +Map.values(%{key1: 1, key2: 2, key3: 3}) ``` ## The Keyword Module @@ -915,7 +920,7 @@ Use [Keyword.get/3](https://hexdocs.pm/elixir/Keyword.html#get/3) to access the ```elixir -[color: "red"] +Keyword.get([color: "red"], :color) ``` Use [Keyword.get/3](https://hexdocs.pm/elixir/Keyword.html#get/3) to access the value for the `:color` key in the following empty list. If the `:color` key does not exist, provide a default value of `"blue"`. @@ -931,7 +936,7 @@ Use [Keyword.get/3](https://hexdocs.pm/elixir/Keyword.html#get/3) to access the ```elixir -[] +Keyword.get([], :color, "blue") ``` Use the [Keyword.keys/1](https://hexdocs.pm/elixir/Keyword.html#keys/1) function to list all of the keys in the following keyword list. @@ -947,7 +952,7 @@ Use the [Keyword.keys/1](https://hexdocs.pm/elixir/Keyword.html#keys/1) function ```elixir -[one: 1, two: 2, three: 3] +Keyword.keys(one: 1, two: 2, three: 3) ``` Use the [Keyword.keyword?/1](https://hexdocs.pm/elixir/Keyword.html#keyword?/1) function to determine if the following is a keyword list. @@ -963,7 +968,7 @@ Use the [Keyword.keyword?/1](https://hexdocs.pm/elixir/Keyword.html#keyword?/1) ```elixir -[key: "value"] +Keyword.keyword?(key: "value") ``` Use the [Keyword.keyword?/1](https://hexdocs.pm/elixir/Keyword.html#keyword?/1) function to determine if an empty list is a keyword list. @@ -981,7 +986,7 @@ Use the [Keyword.keyword?/1](https://hexdocs.pm/elixir/Keyword.html#keyword?/1) ```elixir -[] +Keyword.keyword?([]) ``` Use the [Keyword.keyword?/1](https://hexdocs.pm/elixir/Keyword.html#keyword?/1) function to determine if the following list is a keyword list. @@ -997,7 +1002,7 @@ Use the [Keyword.keyword?/1](https://hexdocs.pm/elixir/Keyword.html#keyword?/1) ```elixir -[1, 2, 3] +Keyword.keyword?([1, 2, 3]) ``` ## Further Reading diff --git a/reading/comprehensions.livemd b/reading/comprehensions.livemd index 9d2eae025..4dffebbc8 100644 --- a/reading/comprehensions.livemd +++ b/reading/comprehensions.livemd @@ -222,7 +222,9 @@ each generator creates another nested loop and therefore has a significant perfo In the Elixir cell below, use a comprehension with a generator of `1..50` to create a list of even integers from `2` to `100`. ```elixir - +for n <- 1..50, rem(n, 2) == 0 do + n +end ``` ## Filters @@ -315,7 +317,9 @@ end ```elixir - +for a <- 1..7, b <- 1..7, c <- 1..7, a + b + c == 7 do + {a, b, c} +end ``` ## Collectables @@ -418,7 +422,9 @@ Enum.map(1..5, fn each -> each * 2 end) ``` ```elixir - +for n <- 1..5, n do + n * 2 +end ``` In the Elixir cell below, convert the following `Enum.reduce` into a comprehension. diff --git a/reading/enum.livemd b/reading/enum.livemd index 64a5398d2..f8859418c 100644 --- a/reading/enum.livemd +++ b/reading/enum.livemd @@ -371,7 +371,7 @@ Use [Enum.map/2](https://hexdocs.pm/elixir/1.12/Enum.html#map/2) to convert a li Enter your solution below. ```elixir - +Enum.map(1..10, fn int -> to_string(int) end) ``` ## Enum.reduce/2 and Enum.reduce/3 @@ -492,7 +492,13 @@ Use [Enum.reduce/3](https://hexdocs.pm/elixir/Enum.html#reduce/3) or [Enum.reduc Enter your solution below. ```elixir - +Enum.reduce(1..10, 0, fn int, acc -> + if rem(int, 2) == 0 do + acc + int + else + acc + end +end) ``` ## Enum.filter @@ -530,7 +536,8 @@ odd_numbers = Enum.filter(1..10, fn integer -> rem(integer, 2) != 0 end) Enter your solution below. ```elixir - +even = Enum.filter(1..10, fn int -> rem(int, 2) == 0 end) +odd = Enum.filter(1..10, fn int -> rem(int, 2) != 0 end) ``` ## Enum.all?/2 @@ -585,6 +592,7 @@ Use [Enum.all/2](https://hexdocs.pm/elixir/Enum.html#all/2) to determine if all ```elixir colors = [:green, :green, :red] +Enum.all?(colors, fn color -> color == :green end) ``` ## Enum.any/2 @@ -628,7 +636,8 @@ Enum.any?(1..10_000_000, fn integer -> is_bitstring(integer) end) Use [Enum.any/2](https://hexdocs.pm/elixir/Enum.html#any/2) to determine if any of the animals in the `animals` list are `:dogs`. You may change the `animals` list to experiment with [Enum.any/2](https://hexdocs.pm/elixir/Enum.html#any/2). ```elixir -[:cats, :dogs, :bears, :lions, :penguins] +animals = [:cats, :dogs, :bears, :lions, :penguins] +Enum.any?(animals, fn animal -> animal == :dogs end) ``` ## Enum.count/1 @@ -656,6 +665,8 @@ In the Elixir cell below, count the number of elements in the `collection`. It s ```elixir collection = [1, 2, 3, 4, 5] + +Enum.count(collection) ``` ## Enum.find/3 @@ -683,7 +694,9 @@ Enum.find(["h", "e", "l", "l", "o"], 10, fn each -> is_integer(each) end) Use [Enum.find/2](https://hexdocs.pm/elixir/Enum.html#find/2) to find the first even integer in this list. ```elixir -[1, "2", "three", 4, "five", 6] +mylist = [1, "2", "three", 4, "five", 6] + +Enum.find(mylist, fn item -> is_integer(item) && rem(item, 2) == 0 end) ``` ## Enum.random/1 @@ -710,7 +723,7 @@ Enum.map(1..10, fn _ -> Enum.random(0..9) end) Enter your solution below. ```elixir - +Enum.random(0..9) ``` ## Capture Operator and Module Functions diff --git a/reading/file.livemd b/reading/file.livemd index 6b33b16f0..d19278092 100644 --- a/reading/file.livemd +++ b/reading/file.livemd @@ -185,7 +185,8 @@ Path.join(path1, path2) Experiment with the functions above. Refer to the documentation for examples you can try. ```elixir - +path = __DIR__ +Path.split(path) ``` ## Bang Functions diff --git a/reading/keyword_lists.livemd b/reading/keyword_lists.livemd index b0d06161b..b8a3d435a 100644 --- a/reading/keyword_lists.livemd +++ b/reading/keyword_lists.livemd @@ -165,7 +165,7 @@ In the Elixir cell below, create a keyword list of your favourite super hero. In Enter your solution below. ```elixir - +[hero1: "superman", hero2: "batman", hero3: "robin"] ``` ## Accessing A Key @@ -184,6 +184,7 @@ Access the `:hello` key in the following keyword list. ```elixir keyword_list = [hello: "world"] +keyword_list[:hello] ``` ## Keyword List Operators @@ -206,13 +207,13 @@ evaluate as a tuple again. Remember that keyword lists are simply lists of tuple In the Elixir cell below, use `++` to add `[one: 1]` to `[two: 2]` to make `[one: 1, two: 2]`. ```elixir - +[one: 1] ++ [two: 2] ``` Remove `[two: 2]` from `[one: 1, two: 2]` to make `[one: 1]`. ```elixir - +[one: 1, two: 2] -- [two: 2] ``` ## Pattern Matching @@ -274,7 +275,8 @@ Bind `1` in the following keyword list to a variable `one`. Enter your solution below. ```elixir -[one: 1, two: 2, three: 3, four: 4] +[{key, one} | tail] = [one: 1, two: 2, three: 3, four: 4] +one ``` ## Further Reading diff --git a/reading/maps.livemd b/reading/maps.livemd index 3fc6d2a1c..f75b8f24a 100644 --- a/reading/maps.livemd +++ b/reading/maps.livemd @@ -193,6 +193,8 @@ map[:hello] ```elixir map = %{hello: "world"} +map.hello +map[:hello] ``` ### Updating Maps @@ -253,7 +255,9 @@ todo = %{title: "finish maps exercise", completed: false} ```elixir - +todo = %{title: "finish maps exercises", completed: false} +updated = %{todo | completed: true} +updated.completed ``` ## Pattern Matching @@ -332,7 +336,8 @@ Bind `2` and `4` in the following map to variables `two` and `four`. Enter your solution below. ```elixir -%{one: 1, two: 2, three: 3, four: 4} +%{two: two, four: four} = %{one: 1, two: 2, three: 3, four: 4} +four ``` ## Further Reading diff --git a/reading/modules.livemd b/reading/modules.livemd index 13b965088..1bf6dbdc6 100644 --- a/reading/modules.livemd +++ b/reading/modules.livemd @@ -308,7 +308,13 @@ end Enter your solution below. ```elixir +defmodule Languages.German do + def greeting do + "Guten Tag" + end +end +Languages.German.greeting() ``` ### Nested Modules @@ -347,8 +353,8 @@ We use the `@` symbol to define a compile-time module attribute. ```elixir defmodule Hero do - @name "Spider-Man" - @nemesis "Green Goblin" + @name "Batman" + @nemesis "Penguin" def introduce do "Hello, my name is #{@name}!" @@ -506,7 +512,29 @@ end ```elixir +defmodule Math do + @moduledoc """ + Math Module + Module demonstrates 2 functions with same name and different arity + """ + + @doc """ + add/2 + """ + def add(a, b) do + a + b + end + + @doc """ + add/3 + """ + def add(a, b, c) do + a + b + c + end +end +Math.add(2, 3) +Math.add(2, 3, 4) ``` ## Default Arguments @@ -573,7 +601,14 @@ Greeting.hello("Andrew") ``` ```elixir +defmodule Greeting do + def hello(name \\ "fubar") do + "Hello #{name}" + end +end +Greeting.hello("extra fubar") +Greeting.hello() ``` ## Documentation @@ -658,7 +693,7 @@ defmodule DoctestFailure do "expected return value" """ def test do - "actual return value" + "expected return value" end end ``` @@ -686,25 +721,27 @@ If this is the case, you either have to fix your code, or remove/comment the cra Uncomment the following code and evaluate the cell to see an example. Re-comment your code to avoid crashing the livebook as you continue with the lesson. ```elixir -# defmodule DoctestCrash do -# @moduledoc """ -# DoctestCrash +defmodule DoctestCrash do + @moduledoc """ + DoctestCrash -# Explains doctest crashes with examples -# """ + Explains doctest crashes with examples + """ -# @doc """ -# Purposely crashes doctest using invalid pattern matching + @doc """ + Purposely crashes doctest using invalid pattern matching -# ## Examples + ## Examples -# iex> {} = DoctestCrash.crash() -# "2" -# """ -# def crash do + iex> DoctestCrash.crash() + "2" + """ + def crash do + "2" + end +end -# end -# end +DoctestCrash.crash() ``` ### Your Turn diff --git a/reading/non_enumerables.livemd b/reading/non_enumerables.livemd index 724734dd2..cabb378ca 100644 --- a/reading/non_enumerables.livemd +++ b/reading/non_enumerables.livemd @@ -57,7 +57,7 @@ Integer.digits(123) In the Elixir cell below, convert the integer `4389` into a list of digits. ```elixir - +Integer.digits(4389) ``` ### Undigits @@ -138,7 +138,7 @@ Now your string is an enumerable list of characters. In the Elixir cell below, convert the string `"Hello, world!"` into a list of single characters. ```elixir - +String.split("Hello, world!", "") ``` ### Joining Strings @@ -216,6 +216,7 @@ defmodule CharacterCount do 4 """ def count(string) do + Enum.count(String.split(string, "", trim: true)) end end ``` diff --git a/reading/protocols.livemd b/reading/protocols.livemd index 03f2e357d..c11de4c48 100644 --- a/reading/protocols.livemd +++ b/reading/protocols.livemd @@ -193,7 +193,13 @@ end ```elixir +defimpl Adder, for: List do + def add(list1, list2) do + list1 ++ list2 + end +end +Adder.add([1], [2]) ``` ## Protocols With Structs @@ -245,8 +251,21 @@ Sound.say(%Cat{mood: :angry}) ```elixir defmodule Dog do - defstruct [] + defstruct [:mood] +end +``` + +```elixir +defimpl Sound, for: Dog do + def say(dog) do + case dog.mood do + :happy -> "Bark!" + :angry -> "Growl!" + end + end end + +Sound.say(%Dog{mood: :happy}) ``` Define a `Sound` implementation for the `Dog` struct above. diff --git a/reading/ranges.livemd b/reading/ranges.livemd index 342c427b9..e089b5708 100644 --- a/reading/ranges.livemd +++ b/reading/ranges.livemd @@ -121,7 +121,7 @@ In the Elixir cell below, use [Enum.to_list/1](https://hexdocs.pm/elixir/Enum.ht ```elixir - +Enum.to_list(3..9//3) ``` ### Pattern Matching With Ranges diff --git a/reading/start_here.livemd b/reading/start_here.livemd index 6e4bfd8ae..91ef12af0 100644 --- a/reading/start_here.livemd +++ b/reading/start_here.livemd @@ -99,6 +99,10 @@ There is a **Commit Your Progress** and a **Mark as Completed** section at the e However, self-led students can complete these sections if they want to track their progress and get more practice using GitHub. We ask that you don't create pull requests to the DockYard Academy repo, as this spams our PR tracker. If you are not an academy student, we also ask that you refrain from @mentioning the instructor as this spams our notifications, and 1-1 feedback is only available to academy students. +```elixir +2 + 2 +``` + ## Mark As Completed diff --git a/reading/strings_and_binaries.livemd b/reading/strings_and_binaries.livemd index d1be8eff8..b5a4ce294 100644 --- a/reading/strings_and_binaries.livemd +++ b/reading/strings_and_binaries.livemd @@ -85,6 +85,10 @@ Each byte stores an integer between `1` and `255` in binary. These integers are ?A ``` +```elixir +?Z +``` + We can also see that a string is actually a series of binary bytes representing a codepoint using [IO.inspect/2](https://hexdocs.pm/elixir/IO.html#inspect/2) with the `binaries: :as_binaries` option. ```elixir @@ -218,13 +222,13 @@ String.graphemes("eĢ") Use [String.graphemes/1](https://hexdocs.pm/elixir/String.html#graphemes/1) to convert the [woman fire fighter](https://emojipedia.org/woman-firefighter/) emoji šŸ‘©ā€šŸš’ to a list of graphemes. ```elixir - +String.graphemes("šŸ‘©ā€šŸš’") ``` Use [String.codepoints/1](https://hexdocs.pm/elixir/String.html#codepoints/1) to convert the emoji šŸ‘©ā€šŸš’ into a list of codepoints. You'll notice it's actually a combination of the šŸ‘© and šŸš’ emojis. ```elixir - +String.codepoints("šŸ‘©ā€šŸš’") ``` ## Hexadecimal @@ -316,7 +320,7 @@ Use hexadecimal `0x` syntax to represent the number `15`. ```elixir - +0xF ``` ## Bitstrings @@ -416,7 +420,7 @@ Convert the alphabet `"abcdefghijklmnopqrstuvwxyz"` to a charlist, then inspect ```elixir - +IO.inspect(String.to_charlist("abcdefghijklmnopqrstuvwxyz"), charlists: :as_lists) ``` ## Further Reading diff --git a/reading/typespecs.livemd b/reading/typespecs.livemd index 0b435ac7b..8ee71e39b 100644 --- a/reading/typespecs.livemd +++ b/reading/typespecs.livemd @@ -66,6 +66,7 @@ In the `Adder` module below, create an `@spec` for integers with the `add/2` fun ```elixir defmodule Adder do + @spec add(integer(), integer()) :: integer() def add(integer1, integer2) do integer1 + integer2 end @@ -108,6 +109,7 @@ In the `Math` module below, define a custom `@type` `input()` that can be a list ```elixir defmodule Math do + @type mynumber :: list() | integer() | charlist() end ```