diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..138f64f --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +elixir/**/_build/ diff --git a/elixir/basketball-website/.exercism/config.json b/elixir/basketball-website/.exercism/config.json new file mode 100644 index 0000000..ec5f089 --- /dev/null +++ b/elixir/basketball-website/.exercism/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "neenjaw" + ], + "contributors": [ + "angelikatyborska", + "NobbZ" + ], + "files": { + "solution": [ + "lib/basketball_website.ex" + ], + "test": [ + "test/basketball_website_test.exs" + ], + "exemplar": [ + ".meta/exemplar.ex" + ] + }, + "language_versions": ">=1.10", + "blurb": "Learn about Access Behaviour by helping extract deeply nested data for the basketball team's website." +} diff --git a/elixir/basketball-website/.exercism/metadata.json b/elixir/basketball-website/.exercism/metadata.json new file mode 100644 index 0000000..845b929 --- /dev/null +++ b/elixir/basketball-website/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"basketball-website","id":"62c61d3995094446ad2e8d13594f8e4f","url":"https://exercism.org/tracks/elixir/exercises/basketball-website","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/basketball-website/.formatter.exs b/elixir/basketball-website/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/basketball-website/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/basketball-website/.gitignore b/elixir/basketball-website/.gitignore new file mode 100644 index 0000000..d5af801 --- /dev/null +++ b/elixir/basketball-website/.gitignore @@ -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"). +access-*.tar + diff --git a/elixir/basketball-website/HELP.md b/elixir/basketball-website/HELP.md new file mode 100644 index 0000000..1c0e91e --- /dev/null +++ b/elixir/basketball-website/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/basketball_website.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/basketball-website/HINTS.md b/elixir/basketball-website/HINTS.md new file mode 100644 index 0000000..e0a5044 --- /dev/null +++ b/elixir/basketball-website/HINTS.md @@ -0,0 +1,18 @@ +# Hints + +## General + +- Read about the [`Access` behaviour][access-behaviour] in the documentation. + +## 1. Extract data from a nested map structure + +- First tokenize the string path to a usable state. You can make use of [`String` module functions][string-module]. +- Write a recursive function to traverse the nested-map structure to retrieve the value or return `nil`. + +## 2. Refactor using included functions + +- Read through the various [`Kernel` module functions][kernel-module], to find one that might shorten/simplify your approach. + +[kernel-module]: https://hexdocs.pm/elixir/Kernel.html#functions +[string-module]: https://hexdocs.pm/elixir/String.html#functions +[access-behaviour]: https://hexdocs.pm/elixir/Access.html \ No newline at end of file diff --git a/elixir/basketball-website/README.md b/elixir/basketball-website/README.md new file mode 100644 index 0000000..a784236 --- /dev/null +++ b/elixir/basketball-website/README.md @@ -0,0 +1,82 @@ +# Basketball Website + +Welcome to Basketball Website 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 + +## Access Behaviour + +Elixir uses code _Behaviours_ to provide common generic interfaces while facilitating specific implementations for each module which implements it. One such common example is the _Access Behaviour_. + +The _Access Behaviour_ provides a common interface for retrieving data from a key-based data structure. The _Access Behaviour_ is implemented for maps and keyword lists, but let's look at its use for maps to get a feel for it. _Access Behaviour_ specifies that when you have a map, you may follow it with _square brackets_ and then use the key to retrieve the value associated with that key. + +```elixir +# Suppose we have these two maps defined (note the difference in the key type) +my_map = %{key: "my value"} +your_map = %{"key" => "your value"} + +# Obtain the value using the Access Behaviour +my_map[:key] == "my value" +your_map[:key] == nil +your_map["key"] == "your value" +``` + +If the key does not exist in the data structure, then `nil` is returned. This can be a source of unintended behavior, because it does not raise an error. Note that `nil` itself implements the Access Behaviour and always returns `nil` for any key. + +## Instructions + +You are working with a web development team to maintain a website for a local basketball team. The web development team is less familiar with Elixir and is asking for a function to be able to extract data from a series of nested maps to facilitate rapid development. + +## 1. Extract data from a nested map structure + +Implement the `extract_from_path/2` function to take two arguments: + +- `data`: a nested map structure with data about the basketball team. +- `path`: a string consisting of period-delimited keys to obtain the value associated with the last key. + +If the value or the key does not exist at any point in the path, `nil` should be returned + +```elixir +data = %{ + "team_mascot" => %{ + "animal" => "bear", + "actor" => %{ + "first_name" => "Noel" + } + } +} +BasketballWebsite.extract_from_path(data, "team_mascot.animal") +# => "bear" +BasketballWebsite.extract_from_path(data, "team_mascot.colors") +# => nil +``` + +Use the _Access Behaviour_ when implementing this function. + +Do not use any `Map` or `Kernel` module functions for working with the nested map data structure. + +## 2. Refactor using included functions + +Your coworker reviewing your code tells you about a `Kernel` module function which does something very similar to your implementation. + +Implement `get_in_path/2` to use this `Kernel` module function. + +The arguments expected are the same as part 1. + +```elixir +BasketballWebsite.get_in_path(data, "team_mascot.actor.first_name") +# => "Noel" +``` + +## Source + +### Created by + +- @neenjaw + +### Contributed to by + +- @angelikatyborska +- @NobbZ \ No newline at end of file diff --git a/elixir/basketball-website/lib/basketball_website.ex b/elixir/basketball-website/lib/basketball_website.ex new file mode 100644 index 0000000..96df851 --- /dev/null +++ b/elixir/basketball-website/lib/basketball_website.ex @@ -0,0 +1,15 @@ +defmodule BasketballWebsite do + def extract_from_path(data, path) do + paths = String.split(path, ".") + root = Enum.at(paths, 0) + if length(paths) > 1 and data[root] do + extract_from_path(data[root], Enum.slice(paths, 1..-1) |> Enum.join(".")) + else + data[root] + end + end + + def get_in_path(data, path) do + Kernel.get_in(data, String.split(path, ".")) + end +end diff --git a/elixir/basketball-website/mix.exs b/elixir/basketball-website/mix.exs new file mode 100644 index 0000000..e653239 --- /dev/null +++ b/elixir/basketball-website/mix.exs @@ -0,0 +1,28 @@ +defmodule BasketballWebsite.MixProject do + use Mix.Project + + def project do + [ + app: :basketball_website, + 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 diff --git a/elixir/basketball-website/test/basketball_website_test.exs b/elixir/basketball-website/test/basketball_website_test.exs new file mode 100644 index 0000000..5224806 --- /dev/null +++ b/elixir/basketball-website/test/basketball_website_test.exs @@ -0,0 +1,335 @@ +defmodule BasketballWebsiteTest do + use ExUnit.Case + + describe "extract_from_path retrieves from" do + @tag task_id: 1 + test "first layer" do + team_data = %{ + "coach" => %{}, + "team_name" => "Hoop Masters", + "players" => %{} + } + + assert BasketballWebsite.extract_from_path(team_data, "team_name") == "Hoop Masters" + end + + @tag task_id: 1 + test "second layer" do + team_data = %{ + "coach" => %{ + "first_name" => "Jane", + "last_name" => "Brown" + }, + "team_name" => "Hoop Masters", + "players" => %{} + } + + assert BasketballWebsite.extract_from_path(team_data, "coach.first_name") == "Jane" + end + + @tag task_id: 1 + test "third layer" do + team_data = %{ + "coach" => %{}, + "team_name" => "Hoop Masters", + "players" => %{ + "99" => %{ + "first_name" => "Amalee", + "last_name" => "Tynemouth", + "email" => "atynemouth0@yellowpages.com", + "statistics" => %{} + }, + "98" => %{ + "first_name" => "Tiffie", + "last_name" => "Derle", + "email" => "tderle1@vimeo.com", + "statistics" => %{} + } + } + } + + assert BasketballWebsite.extract_from_path(team_data, "players.99.first_name") == "Amalee" + end + + @tag task_id: 1 + test "fourth layer" do + team_data = %{ + "coach" => %{}, + "team_name" => "Hoop Masters", + "players" => %{ + "42" => %{ + "first_name" => "Conchita", + "last_name" => "Elham", + "email" => "celham4@wikia.com", + "statistics" => %{ + "average_points_per_game" => 4.6, + "free_throws_made" => 7, + "free_throws_attempted" => 10 + } + }, + "61" => %{ + "first_name" => "Noel", + "last_name" => "Fawlkes", + "email" => "nfawlkes5@yahoo.co.jp", + "statistics" => %{ + "average_points_per_game" => 5.0, + "free_throws_made" => 5, + "free_throws_attempted" => 5 + } + } + } + } + + assert BasketballWebsite.extract_from_path( + team_data, + "players.61.statistics.average_points_per_game" + ) === 5.0 + end + end + + describe "extract_from_path returns nil from nonexistent last key in" do + @tag task_id: 1 + test "first layer" do + team_data = %{ + "coach" => %{}, + "team_name" => "Hoop Masters", + "players" => %{} + } + + assert BasketballWebsite.extract_from_path(team_data, "team_song") == nil + end + + @tag task_id: 1 + test "second layer" do + team_data = %{ + "coach" => %{ + "first_name" => "Jane", + "last_name" => "Brown" + }, + "team_name" => "Hoop Masters", + "players" => %{} + } + + assert BasketballWebsite.extract_from_path(team_data, "coach.age") == nil + end + + @tag task_id: 1 + test "third layer" do + team_data = %{ + "coach" => %{}, + "team_name" => "Hoop Masters", + "players" => %{ + "32" => %{ + "first_name" => "Deni", + "last_name" => "Lidster", + "email" => nil, + "statistics" => %{} + } + } + } + + assert BasketballWebsite.extract_from_path(team_data, "players.32.height") == nil + end + + @tag task_id: 1 + test "fourth layer" do + team_data = %{ + "coach" => %{}, + "team_name" => "Hoop Masters", + "players" => %{ + "12" => %{ + "first_name" => "Andy", + "last_name" => "Napoli", + "email" => "anapoli7@goodreads.com", + "statistics" => %{ + "average_points_per_game" => 7 + } + } + } + } + + assert BasketballWebsite.extract_from_path( + team_data, + "players.12.statistics.personal_fouls" + ) == nil + end + end + + @tag task_id: 1 + test "extract_from_path returns nil from nonexistent path" do + team_data = %{ + "coach" => %{}, + "team_name" => "Hoop Masters", + "players" => %{} + } + + assert BasketballWebsite.extract_from_path( + team_data, + "support_personnel.physiotherapy.first_name" + ) == nil + end + + describe "get_in_path retrieves from" do + @tag task_id: 2 + test "first layer" do + team_data = %{ + "coach" => %{}, + "team_name" => "Hoop Masters", + "players" => %{} + } + + assert BasketballWebsite.get_in_path(team_data, "team_name") == "Hoop Masters" + end + + @tag task_id: 2 + test "second layer" do + team_data = %{ + "coach" => %{ + "first_name" => "Jane", + "last_name" => "Brown" + }, + "team_name" => "Hoop Masters", + "players" => %{} + } + + assert BasketballWebsite.get_in_path(team_data, "coach.first_name") == "Jane" + end + + @tag task_id: 2 + test "third layer" do + team_data = %{ + "coach" => %{}, + "team_name" => "Hoop Masters", + "players" => %{ + "99" => %{ + "first_name" => "Amalee", + "last_name" => "Tynemouth", + "email" => "atynemouth0@yellowpages.com", + "statistics" => %{} + }, + "98" => %{ + "first_name" => "Tiffie", + "last_name" => "Derle", + "email" => "tderle1@vimeo.com", + "statistics" => %{} + } + } + } + + assert BasketballWebsite.get_in_path(team_data, "players.99.first_name") == "Amalee" + end + + @tag task_id: 2 + test "fourth layer" do + team_data = %{ + "coach" => %{}, + "team_name" => "Hoop Masters", + "players" => %{ + "42" => %{ + "first_name" => "Conchita", + "last_name" => "Elham", + "email" => "celham4@wikia.com", + "statistics" => %{ + "average_points_per_game" => 4.6, + "free_throws_made" => 7, + "free_throws_attempted" => 10 + } + }, + "61" => %{ + "first_name" => "Noel", + "last_name" => "Fawlkes", + "email" => "nfawlkes5@yahoo.co.jp", + "statistics" => %{ + "average_points_per_game" => 5.0, + "free_throws_made" => 5, + "free_throws_attempted" => 5 + } + } + } + } + + assert BasketballWebsite.get_in_path( + team_data, + "players.61.statistics.average_points_per_game" + ) === 5.0 + end + end + + describe "get_in_path returns nil from nonexistent last key in" do + @tag task_id: 2 + test "first layer" do + team_data = %{ + "coach" => %{}, + "team_name" => "Hoop Masters", + "players" => %{} + } + + assert BasketballWebsite.get_in_path(team_data, "team_song") == nil + end + + @tag task_id: 2 + test "second layer" do + team_data = %{ + "coach" => %{ + "first_name" => "Jane", + "last_name" => "Brown" + }, + "team_name" => "Hoop Masters", + "players" => %{} + } + + assert BasketballWebsite.get_in_path(team_data, "coach.age") == nil + end + + @tag task_id: 2 + test "third layer" do + team_data = %{ + "coach" => %{}, + "team_name" => "Hoop Masters", + "players" => %{ + "32" => %{ + "first_name" => "Deni", + "last_name" => "Lidster", + "email" => nil, + "statistics" => %{} + } + } + } + + assert BasketballWebsite.get_in_path(team_data, "players.32.height") == nil + end + + @tag task_id: 2 + test "fourth layer" do + team_data = %{ + "coach" => %{}, + "team_name" => "Hoop Masters", + "players" => %{ + "12" => %{ + "first_name" => "Andy", + "last_name" => "Napoli", + "email" => "anapoli7@goodreads.com", + "statistics" => %{ + "average_points_per_game" => 7 + } + } + } + } + + assert BasketballWebsite.get_in_path(team_data, "players.12.statistics.personal_fouls") == + nil + end + end + + @tag task_id: 2 + test "get_in_path returns nil from nonexistent path" do + team_data = %{ + "coach" => %{}, + "team_name" => "Hoop Masters", + "players" => %{} + } + + assert BasketballWebsite.get_in_path(team_data, "support_personnel.physiotherapy.first_name") == + nil + end +end diff --git a/elixir/basketball-website/test/test_helper.exs b/elixir/basketball-website/test/test_helper.exs new file mode 100644 index 0000000..e8677a3 --- /dev/null +++ b/elixir/basketball-website/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true, seed: 0) diff --git a/elixir/captains-log/.exercism/config.json b/elixir/captains-log/.exercism/config.json new file mode 100644 index 0000000..ac9a502 --- /dev/null +++ b/elixir/captains-log/.exercism/config.json @@ -0,0 +1,21 @@ +{ + "authors": [ + "angelikatyborska" + ], + "contributors": [ + "neenjaw" + ], + "files": { + "solution": [ + "lib/captains_log.ex" + ], + "test": [ + "test/captains_log_test.exs" + ], + "exemplar": [ + ".meta/exemplar.ex" + ] + }, + "language_versions": ">=1.10", + "blurb": "Learn about randomness and using Erlang libraries from Elixir by helping Mary generate stardates and starship registry numbers for her Star Trek themed pen-and-paper role playing sessions." +} diff --git a/elixir/captains-log/.exercism/metadata.json b/elixir/captains-log/.exercism/metadata.json new file mode 100644 index 0000000..07fd567 --- /dev/null +++ b/elixir/captains-log/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"captains-log","id":"42e6cfb7bfa94354a2597ab82ac8a8ba","url":"https://exercism.org/tracks/elixir/exercises/captains-log","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/captains-log/.formatter.exs b/elixir/captains-log/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/captains-log/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/captains-log/.gitignore b/elixir/captains-log/.gitignore new file mode 100644 index 0000000..4abee35 --- /dev/null +++ b/elixir/captains-log/.gitignore @@ -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"). +match_binary-*.tar + diff --git a/elixir/captains-log/HELP.md b/elixir/captains-log/HELP.md new file mode 100644 index 0000000..e6b15c1 --- /dev/null +++ b/elixir/captains-log/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/captains_log.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/captains-log/HINTS.md b/elixir/captains-log/HINTS.md new file mode 100644 index 0000000..fdae40c --- /dev/null +++ b/elixir/captains-log/HINTS.md @@ -0,0 +1,38 @@ +# Hints + +## General + +- Read about using Erlang libraries in the [official Getting Started guide][getting-started-erlang-libraries], and in particular about [formatting strings][getting-started-formatted-text-output]. + +## 1. Generate a random planet + +- Use the provided module attribute with a list of letters representing planetary classes. +- There is a [built-in function][enum-random] for choosing an element from a list at random. + +## 2. Generate a random starship registry number + +- There is a [build-in function][enum-random] for choosing an element from a range at random. + +## 3. Generate a random stardate + +- There is no Elixir function that would return a random float. +- There is a [built-in Erlang function][erl-rand-uniform] that returns a random float x where `0.0 <= x < 1.0`. +- If `x` belongs to a range `0.0 <= x < 1.0`, but you need a number from a different range `a <= x < b`, you can shift x's range by multiplying it by the range's width (`b - a`) and adding the range's start (`a`). That is: `x * (b - a) + a`. + +## 4. Format the stardate + +- There is no Elixir function that would be able to, in a single step, format a float as a string with a given precision. +- There is a [built-in Erlang function][erl-io-lib-format] that takes a format string and a list of data, and returns a charlist. +- There is a [built-in function][to-string] that changes a charlist to a string. +- The format string of that function contains control sequences. +- A control sequence starts with `~` and has the pattern `~F.P.PadModC`, where `F` stands for the width of the output, `P` stands for the precision, `Pad` stands for the padding character, `Mod` stands for the control sequence modifier, and `C` is the type of the control sequence. +- To format a float with a desired precision, a control sequence with the pattern `~.PC` will suffice. +- The control sequence type for floats is `f`. +- The exact format string you need is `~.1f`. + +[getting-started-erlang-libraries]: https://elixir-lang.org/getting-started/erlang-libraries.html +[getting-started-formatted-text-output]: https://elixir-lang.org/getting-started/erlang-libraries.html#formatted-text-output +[enum-random]: https://hexdocs.pm/elixir/Enum.html#random/1 +[erl-rand-uniform]: http://www.erlang.org/doc/man/rand.html#uniform-0 +[erl-io-lib-format]: http://www.erlang.org/doc/man/io_lib.html#format-2 +[to-string]: https://hexdocs.pm/elixir/Kernel.html#to_string/1 \ No newline at end of file diff --git a/elixir/captains-log/README.md b/elixir/captains-log/README.md new file mode 100644 index 0000000..7c0f878 --- /dev/null +++ b/elixir/captains-log/README.md @@ -0,0 +1,103 @@ +# Captain's Log + +Welcome to Captain's Log 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 + +## Randomness + +In Elixir, to choose a random element from an enumerable data structure (e.g. list, range), we use `Enum.random`. This function will pick a single element, with every element having equal probability of being picked. + +Elixir does not have its own functions for picking a random float. To do that, we have to use Erlang directly. + +## Erlang Libraries + +Elixir code runs in the BEAM virtual machine. BEAM is part of the Erlang Run-Time System. Being inspired by Erlang, and sharing its run environment, Elixir provides great interoperability with Erlang libraries. This means that Elixir developers can use Erlang libraries from within their Elixir code. In fact, writing Elixir libraries for functionality already provided by Erlang libraries is discouraged in the Elixir community. + +As a result, certain functionality, like mathematical operations or timer functions, is only available in Elixir via Erlang. + +Erlang's standard library is available for use in our Elixir code without any extra steps necessary. + +Erlang functions can be called in the same way we call Elixir functions, with one small difference. Erlang module names are `snake_case` atoms. For example, to call the Erlang `pi/0` function from the `math` module, one would write: + +```elixir +:math.pi() +# => 3.141592653589793 +``` + +The most commonly used Erlang functions that do not have an Elixir equivalent are: + +- `:timer.sleep/1` which suspends a process for the given amount of milliseconds. +- `:rand.uniform/0` which generates a random float `x`, where `0.0 <= x < 1.0`. +- `:io_lib.format/2` which provides C-style string formatting (using control sequences). Using this function, we could for example print an integer in any base between 2 and 36 or format a float with desired precision. Note that this function, like many Erlang functions, returns a charlist. +- The `math` module that provides mathematical functions such as `sin/1`, `cos/1`, `log2/1`, `log10/1`, `pow/2`, and more. + +To discover Erlang's standard library, explore the [STDLIB Reference Manual][erl-stdlib-ref]. + +[erl-stdlib-ref]: http://www.erlang.org/doc/apps/stdlib/index.html + +## Instructions + +Mary is a big fan of the TV series _Star Trek: The Next Generation_. She often plays pen-and-paper role playing games, where she and her friends pretend to be the crew of the _Starship Enterprise_. Mary's character is Captain Picard, which means she has to keep the captain's log. She loves the creative part of the game, but doesn't like to generate random data on the spot. + +Help Mary by creating random generators for data commonly appearing in the captain's log. + +## 1. Generate a random planet + +The _Starship Enterprise_ encounters many planets in its travels. Planets in the Star Trek universe are split into categories based on their properties. For example, Earth is a class M planet. All possible planetary classes are: D, H, J, K, L, M, N, R, T, and Y. + +Implement the `random_planet_class/0` function. It should return one of the planetary classes at random. + +```elixir +CaptainsLog.random_planet_class() +# => "K" +``` + +## 2. Generate a random starship registry number + +Enterprise (registry number NCC-1701) is not the only starship flying around! When it rendezvous with another starship, Mary needs to log the registry number of that starship. + +Registry numbers start with the prefix "NCC-" and then use a number from 1000 to 9999 (inclusive). + +Implement the `random_ship_registry_number/0` function that returns a random starship registry number. + +```elixir +CaptainsLog.random_ship_registry_number() +# => "NCC-1947" +``` + +## 3. Generate a random stardate + +What's the use of a log if it doesn't include dates? + +A stardate is a floating point number. The adventures of the _Starship Enterprise_ from the first season of _The Next Generation_ take place between the stardates 41000.0 and 42000.0. The "4" stands for the 24th century, the "1" for the first season. + +Implement the function `random_stardate/0` that returns a floating point number between 41000.0 (inclusive) and 42000.0 (exclusive). + +```elixir +CaptainsLog.random_stardate() +# => 41458.15721310934 +``` + +## 4. Format the stardate + +In the captain's log, stardates are usually rounded to a single decimal place. + +Implement the `format_stardate/1` function that will take a floating point number and return a string with the number rounded to a single decimal place. + +```elixir +CaptainsLog.format_stardate(41458.15721310934) +# => "41458.2" +``` + +## Source + +### Created by + +- @angelikatyborska + +### Contributed to by + +- @neenjaw \ No newline at end of file diff --git a/elixir/captains-log/lib/captains_log.ex b/elixir/captains-log/lib/captains_log.ex new file mode 100644 index 0000000..f6fcf8f --- /dev/null +++ b/elixir/captains-log/lib/captains_log.ex @@ -0,0 +1,21 @@ +defmodule CaptainsLog do + @planetary_classes ["D", "H", "J", "K", "L", "M", "N", "R", "T", "Y"] + + def random_planet_class() do + Enum.random(@planetary_classes) + end + + def random_ship_registry_number() do + n = Enum.random(1000..9999) + "NCC-#{n}" + end + + def random_stardate() do + 41000.0 + :rand.uniform() * 1000 + end + + def format_stardate(stardate) when is_float(stardate) do + :io_lib.format("~.1f", [stardate]) |> String.Chars.to_string() + end + def format_stardate(_), do: raise ArgumentError +end diff --git a/elixir/captains-log/mix.exs b/elixir/captains-log/mix.exs new file mode 100644 index 0000000..dd2a693 --- /dev/null +++ b/elixir/captains-log/mix.exs @@ -0,0 +1,28 @@ +defmodule CaptainsLog.MixProject do + use Mix.Project + + def project do + [ + app: :captains_log, + 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 diff --git a/elixir/captains-log/test/captains_log_test.exs b/elixir/captains-log/test/captains_log_test.exs new file mode 100644 index 0000000..2f25689 --- /dev/null +++ b/elixir/captains-log/test/captains_log_test.exs @@ -0,0 +1,119 @@ +defmodule CaptainsLogTest do + use ExUnit.Case + + describe "random_planet_class" do + @tag task_id: 1 + test "it always returns one of the letters: D, H, J, K, L, M, N, R, T, Y" do + planetary_classes = ["D", "H", "J", "K", "L", "M", "N", "R", "T", "Y"] + + Enum.each(0..100, fn _ -> + assert CaptainsLog.random_planet_class() in planetary_classes + end) + end + + @tag task_id: 1 + test "it will eventually return each of the letters at least once" do + planetary_classes = ["D", "H", "J", "K", "L", "M", "N", "R", "T", "Y"] + + never_returned_planetary_classes = + Enum.reduce_while(0..1000, planetary_classes, fn _, remaining_planetary_classes -> + if remaining_planetary_classes == [] do + {:halt, remaining_planetary_classes} + else + {:cont, remaining_planetary_classes -- [CaptainsLog.random_planet_class()]} + end + end) + + assert never_returned_planetary_classes == [] + end + end + + describe "random_ship_registry_number" do + @tag task_id: 2 + test "start with \"NCC-\"" do + assert String.starts_with?(CaptainsLog.random_ship_registry_number(), "NCC-") + end + + @tag task_id: 2 + test "ends with a random integer between 1000 and 9999" do + Enum.each(0..100, fn _ -> + random_ship_registry_number = CaptainsLog.random_ship_registry_number() + just_the_number = String.replace(random_ship_registry_number, "NCC-", "") + + case Integer.parse(just_the_number) do + {integer, ""} -> + assert integer >= 1000 + assert integer <= 9999 + + _ -> + flunk("Expected #{just_the_number} to be an integer") + end + end) + end + end + + describe "random_stardate" do + @tag task_id: 3 + test "is a float" do + assert is_float(CaptainsLog.random_stardate()) + end + + @tag task_id: 3 + test "is equal to or greater than 41_000.0" do + Enum.each(0..100, fn _ -> + assert CaptainsLog.random_stardate() >= 41_000.0 + end) + end + + @tag task_id: 3 + test "is less than 42_000.0" do + Enum.each(0..100, fn _ -> + assert CaptainsLog.random_stardate() < 42_000.0 + end) + end + + @tag task_id: 3 + test "consecutive calls return floats with different fractional parts" do + decimal_parts = + Enum.map(0..10, fn _ -> + random_stardate = CaptainsLog.random_stardate() + Float.ceil(random_stardate) - random_stardate + end) + + assert Enum.count(Enum.uniq(decimal_parts)) > 3 + end + + @tag task_id: 3 + test "returns floats with fractional parts with more than one decimal place" do + decimal_parts = + Enum.map(0..10, fn _ -> + random_stardate = CaptainsLog.random_stardate() + Float.ceil(random_stardate * 10) - random_stardate * 10 + end) + + assert Enum.count(Enum.uniq(decimal_parts)) > 3 + end + end + + describe "format_stardate" do + @tag task_id: 4 + test "returns a string" do + assert is_bitstring(CaptainsLog.format_stardate(41010.7)) + end + + @tag task_id: 4 + test "formats floats" do + assert CaptainsLog.format_stardate(41543.3) == "41543.3" + end + + @tag task_id: 4 + test "rounds floats to one decimal place" do + assert CaptainsLog.format_stardate(41032.4512) == "41032.5" + end + + @tag task_id: 4 + test "does not accept integers" do + assert_raise ArgumentError, fn -> CaptainsLog.format_stardate(41411) end + end + end +end diff --git a/elixir/captains-log/test/test_helper.exs b/elixir/captains-log/test/test_helper.exs new file mode 100644 index 0000000..e8677a3 --- /dev/null +++ b/elixir/captains-log/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true, seed: 0) diff --git a/elixir/city-office/.exercism/config.json b/elixir/city-office/.exercism/config.json new file mode 100644 index 0000000..eb609d4 --- /dev/null +++ b/elixir/city-office/.exercism/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "angelikatyborska" + ], + "contributors": [ + "neenjaw", + "michallepicki" + ], + "files": { + "solution": [ + "lib/form.ex" + ], + "test": [ + "test/form_test.exs" + ], + "exemplar": [ + ".meta/exemplar.ex" + ] + }, + "language_versions": ">=1.10", + "blurb": "Learn about writing documentation and typespecs by getting your code ready for the arrival of a new colleague at the city office." +} diff --git a/elixir/city-office/.exercism/metadata.json b/elixir/city-office/.exercism/metadata.json new file mode 100644 index 0000000..cfde856 --- /dev/null +++ b/elixir/city-office/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"city-office","id":"f8d9471439664a2092d435381c8af052","url":"https://exercism.org/tracks/elixir/exercises/city-office","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/city-office/.formatter.exs b/elixir/city-office/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/city-office/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/city-office/.gitignore b/elixir/city-office/.gitignore new file mode 100644 index 0000000..4abee35 --- /dev/null +++ b/elixir/city-office/.gitignore @@ -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"). +match_binary-*.tar + diff --git a/elixir/city-office/HELP.md b/elixir/city-office/HELP.md new file mode 100644 index 0000000..f171b74 --- /dev/null +++ b/elixir/city-office/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/form.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/city-office/HINTS.md b/elixir/city-office/HINTS.md new file mode 100644 index 0000000..01a107f --- /dev/null +++ b/elixir/city-office/HINTS.md @@ -0,0 +1,63 @@ +# Hints + +## General + +- Read the official documentation for [typespecs][typespecs]. +- Read the official documentation about [writing documentation][writing-documentation]. +- Read about using module attributes as annotations in the [official Getting Started guide][getting-started-module-attributes]. +- Read about using typespecs in the [official Getting Started guide][getting-started-typespecs]. + +## 1. Document the purpose of the form tools + +- The module attribute `@moduledoc` can be used to write documentation for a module. + +## 2. Document filling out fields with blank values + +- The module attribute `@doc` can be used to write documentation for a function. +- The module attribute `@spec` can be used to write a typespec for a function. +- Place the `@doc` and `@spec` attributes right before the first function clause of the function that those attributes describe. +- Refer to the [typespecs documentation][typespecs-types] for a list of all available types. +- The correct type for strings is [defined in the `String` module][string-t]. + +## 3. Document splitting values into lists of uppercase letters + +- The module attribute `@doc` can be used to write documentation for a function. +- The module attribute `@spec` can be used to write a typespec for a function. +- Place the `@doc` and `@spec` attributes right before the first function clause of the function that those attributes describe. +- Refer to the [typespecs documentation][typespecs-types] for a list of all available types. +- The correct type for strings is [defined in the `String` module][string-t]. +- A list is a parametrized type. + +## 4. Document checking if a value fits a field with a max length + +- The module attribute `@doc` can be used to write documentation for a function. +- The module attribute `@spec` can be used to write a typespec for a function. +- Place the `@doc` and `@spec` attributes right before the first function clause of the function that those attributes describe. +- Refer to the [typespecs documentation][typespecs-types] for a list of all available types. +- The correct type for strings is [defined in the `String` module][string-t]. +- Literal values can be used in a typespec. +- The pipe `|` can be used to represent a union of types. + +## 5. Document different address formats + +- The module attribute `@type` can be use to define a custom public type. +- Types can be compound, e.g. when specifying a type that's a map, you can also specify the types of the values under the specific keys. +- [The type operator `::`][type-operator] can also be used to prepend a variable name to a type. +- Custom types can be used to define other custom types. + +## 6. Document formatting the address + +- The module attribute `@doc` can be used to write documentation for a function. +- The module attribute `@spec` can be used to write a typespec for a function. +- Place the `@doc` and `@spec` attributes right before the first function clause of the function that those attributes describe. +- Refer to the [typespecs documentation][typespecs-types] for a list of all available types. +- The correct type for strings is [defined in the `String` module][string-t]. +- Custom types can be used in a typespec. + +[writing-documentation]: https://hexdocs.pm/elixir/writing-documentation.html +[typespecs]: https://hexdocs.pm/elixir/typespecs.html +[typespecs-types]: https://hexdocs.pm/elixir/typespecs.html#types-and-their-syntax +[getting-started-module-attributes]: https://elixir-lang.org/getting-started/module-attributes.html#as-annotations +[getting-started-typespecs]: https://elixir-lang.org/getting-started/typespecs-and-behaviours.html#types-and-specs +[string-t]: https://hexdocs.pm/elixir/String.html#t:t/0 +[type-operator]: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#::/2 \ No newline at end of file diff --git a/elixir/city-office/README.md b/elixir/city-office/README.md new file mode 100644 index 0000000..f34520f --- /dev/null +++ b/elixir/city-office/README.md @@ -0,0 +1,173 @@ +# City Office + +Welcome to City Office 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 + +## Docs + +Documentation in Elixir is a first-class citizen. + +There are two module attributes commonly used to document your code - `@moduledoc` for documenting a module and `@doc` for documenting a function that follows the attribute. The `@moduledoc` attribute usually appears on the first line of the module, and the `@doc` attribute usually appears right before a function definition, or the function's typespec if it has one. The documentation is commonly written in a multiline string using the heredoc syntax. + +Elixir documentation is written in [**Markdown**][markdown]. + +```elixir +defmodule String do + @moduledoc """ + Strings in Elixir are UTF-8 encoded binaries. + """ + + @doc """ + Converts all characters in the given string to uppercase according to `mode`. + + ## Examples + + iex> String.upcase("abcd") + "ABCD" + + iex> String.upcase("olá") + "OLÁ" + """ + def upcase(string, mode \\ :default) +end +``` + +## Typespecs + +Elixir is a dynamically typed language, which means it doesn't provide compile-time type checks. Still, type specifications can be used as a form of documentation. + +A type specification can be added to a function using the `@spec` module attribute right before the function definition. `@spec` is followed by the function name and a list of all of its arguments' types, in parentheses, separated by commas. The type of the return value is separated from the function's arguments with a double colon `::`. + +```elixir +@spec longer_than?(String.t(), non_neg_integer()) :: boolean() +def longer_than?(string, length), do: String.length(string) > length +``` + +### Types + +Most commonly used types include: + +- booleans: `boolean()` +- strings: `String.t()` +- numbers: `integer()`, `non_neg_integer()`, `pos_integer()`, `float()` +- lists: `list()` +- a value of any type: `any()` + +Some types can also be parameterized, for example `list(integer)` is a list of integers. + +Literal values can also be used as types. + +A union of types can be written using the pipe `|`. For example, `integer() | :error` means either an integer or the atom literal `:error`. + +A full list of all types can be found in the ["Typespecs" section in the official documentation][types]. + +### Naming arguments + +Arguments in the typespec could also be named which is useful for distinguishing multiple arguments of the same type. The argument name, followed by a double colon, goes before the argument's type. + +```elixir +@spec to_hex({hue :: integer, saturation :: integer, lightness :: integer}) :: String.t() +``` + +### Custom types + +Typespecs aren't limited to just the built-in types. Custom types can be defined using the `@type` module attribute. A custom type definition starts with the type's name, followed by a double colon and then the type itself. + +```elixir +@type color :: {hue :: integer, saturation :: integer, lightness :: integer} + +@spec to_hex(color()) :: String.t() +``` + +A custom type can be used from the same module where it's defined, or from another module. + +[types]: https://hexdocs.pm/elixir/typespecs.html#types-and-their-syntax +[markdown]: https://docs.github.com/en/github/writing-on-github/basic-writing-and-formatting-syntax + +## Instructions + +You have been working in the city office for a while, and you have developed a set of tools that speed up your day-to-day work, for example with filling out forms. + +Now, a new colleague is joining you, and you realized your tools might not be self-explanatory. There are a lot of weird conventions in your office, like always filling out forms with uppercase letters and avoiding leaving fields empty. + +You decide to write some documentation so that it's easier for your new colleague to hop right in and start using your tools. + +## 1. Document the purpose of the form tools + +Add documentation to the `Form` module that describes its purpose. It should read: + +``` +A collection of loosely related functions helpful for filling out various forms at the city office. +``` + +## 2. Document filling out fields with blank values + +Add documentation and a typespec to the `Form.blanks/1` function. The documentation should read: + +``` +Generates a string of a given length. + +This string can be used to fill out a form field that is supposed to have no value. +Such fields cannot be left empty because a malicious third party could fill them out with false data. +``` + +The typespec should explain that the function accepts a single argument, a non-negative integer, and returns a string. + +## 3. Document splitting values into lists of uppercase letters + +Add documentation and a typespec to the `Form.letters/1` function. The documentation should read: + +``` +Splits the string into a list of uppercase letters. + +This is needed for form fields that don't offer a single input for the whole string, +but instead require splitting the string into a predefined number of single-letter inputs. +``` + +The typespec should explain that the function accepts a single argument, a string, and returns a list of strings. + +## 4. Document checking if a value fits a field with a max length + +Add documentation and a typespec to the `Form.check_length/2` function. The documentation should read: + +``` +Checks if the value has no more than the maximum allowed number of letters. + +This is needed to check that the values of fields do not exceed the maximum allowed length. +It also tells you by how much the value exceeds the maximum. +``` + +The typespec should explain that the function accepts two arguments, a string and a non-negative integer, and returns one of two possible values. It returns either the `:ok` atom or a 2-tuple with the first element being the `:error` atom, and the second a positive integer. + +## 5. Document different address formats + +For some unknown to you reason, the city office's internal system uses two different ways of representing addresses - either as a map or as a tuple. + +Document this fact by defining three custom public types: +- `address_map` - a map with the keys `:street`, `:postal_code`, and `:city`. Each key holds a value of type string. +- `address_tuple` - a tuple with three values - `street`, `postal_code`, and `city`. Each value is of type string. Differentiate the values by giving them names in the typespec. +- `address` - can be either an `address_map` or an `address_tuple`. + +## 6. Document formatting the address + +Add documentation and a typespec to the `Form.format_address/1` function. The documentation should read: + +``` +Formats the address as an uppercase multiline string. +``` + +The typespec should explain that the function accepts one argument, an address, and returns a string. + +## Source + +### Created by + +- @angelikatyborska + +### Contributed to by + +- @neenjaw +- @michallepicki \ No newline at end of file diff --git a/elixir/city-office/lib/form.ex b/elixir/city-office/lib/form.ex new file mode 100644 index 0000000..bdf007e --- /dev/null +++ b/elixir/city-office/lib/form.ex @@ -0,0 +1,65 @@ +defmodule Form do + @moduledoc """ + A collection of loosely related functions helpful for filling out various forms at the city office. + """ + + @doc """ + Generates a string of a given length. + + This string can be used to fill out a form field that is supposed to have no value. + Such fields cannot be left empty because a malicious third party could fill them out with false data. + """ + @spec blanks(non_neg_integer) :: String.t() + def blanks(n) do + String.duplicate("X", n) + end + + @doc """ + Splits the string into a list of uppercase letters. + + This is needed for form fields that don't offer a single input for the whole string, + but instead require splitting the string into a predefined number of single-letter inputs. + """ + @spec letters(String.t()) :: [String.t()] + def letters(word) do + word + |> String.upcase() + |> String.split("", trim: true) + end + + @doc """ + Checks if the value has no more than the maximum allowed number of letters. + + This is needed to check that the values of fields do not exceed the maximum allowed length. + It also tells you by how much the value exceeds the maximum. + """ + @spec check_length(String.t(), non_neg_integer()) :: :ok | {:error, pos_integer()} + def check_length(word, length) do + diff = String.length(word) - length + + if diff <= 0 do + :ok + else + {:error, diff} + end + end + + @type address_map :: %{street: String.t(), postal_code: String.t(), city: String.t()} + @type address_tuple :: {street :: String.t(), postal_code :: String.t(), city :: String.t()} + @type address :: address_map() | address_tuple() + + @doc """ + Formats the address as an uppercase multiline string. + """ + @spec format_address(address()) :: String.t() + def format_address(%{street: street, postal_code: postal_code, city: city}) do + format_address({street, postal_code, city}) + end + + def format_address({street, postal_code, city}) do + """ + #{String.upcase(street)} + #{String.upcase(postal_code)} #{String.upcase(city)} + """ + end +end diff --git a/elixir/city-office/mix.exs b/elixir/city-office/mix.exs new file mode 100644 index 0000000..9e8d828 --- /dev/null +++ b/elixir/city-office/mix.exs @@ -0,0 +1,28 @@ +defmodule Form.MixProject do + use Mix.Project + + def project do + [ + app: :city_office, + 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 diff --git a/elixir/city-office/test/form_test.exs b/elixir/city-office/test/form_test.exs new file mode 100644 index 0000000..0f9623a --- /dev/null +++ b/elixir/city-office/test/form_test.exs @@ -0,0 +1,292 @@ +defmodule FormTest do + use ExUnit.Case + + # Dear Elixir learner, + # If you're reading this test suite to gain some insights, + # please be advised that it is somewhat unusual. + # + # Don't worry if you don't understand this test suite at this stage of your learning journey. + # We had to use some advanced features to be able to write assertions about docs and typespecs. + # You wouldn't normally write assertions for that in a typical codebase. + # We're doing it here strictly for educational purposes. + + defmacrop assert_moduledoc(expected_moduledoc) do + quote do + {:docs_v1, _, _, _, module_doc, _, _} = Code.fetch_docs(Form) + + if module_doc == :none do + flunk("expected the module Form to have documentation") + else + actual_moduledoc = module_doc["en"] + assert actual_moduledoc == unquote(expected_moduledoc) + end + end + end + + defmacrop assert_doc({function_name, function_arity}, expected_doc) do + quote do + {:docs_v1, _, _, _, _, _, docs} = Code.fetch_docs(Form) + + {_, _, _, doc_content, _} = + Enum.find(docs, fn {{kind, function_name, arity}, _, _, _, _} -> + {kind, function_name, arity} == + {:function, unquote(function_name), unquote(function_arity)} + end) + + if doc_content == :none do + flunk( + "expected the function Form.#{unquote(function_name)}/#{unquote(function_arity)} to have documentation" + ) + else + actual_doc = doc_content["en"] + assert actual_doc == unquote(expected_doc) + end + end + end + + defmacrop assert_spec({function_name, function_arity}, arguments_specs, return_spec) do + quote do + {:ok, specs} = Code.Typespec.fetch_specs(Form) + + spec = + Enum.find(specs, fn {{function_name, arity}, _} -> + {function_name, arity} == {unquote(function_name), unquote(function_arity)} + end) + + assert spec, + "expected the function Form.#{unquote(function_name)}/#{unquote(function_arity)} to have a typespec" + + {{unquote(function_name), unquote(function_arity)}, [{:type, _, :fun, _} = function_spec]} = + spec + + {:"::", _, [arguments, return]} = + Code.Typespec.spec_to_quoted(unquote(function_name), function_spec) + + accepted_arguments_specs = + Enum.map(unquote(arguments_specs), fn arguments_spec -> + "#{unquote(function_name)}(#{arguments_spec})" + end) + + actual_arguments_spec = Macro.to_string(arguments) + assert actual_arguments_spec in accepted_arguments_specs + + expected_return_spec = unquote(return_spec) + actual_return_spec = Macro.to_string(return) + assert actual_return_spec == expected_return_spec + end + end + + defmacrop assert_type({module_name, type_name}, expected_type_definition) do + quote do + {:ok, types} = Code.Typespec.fetch_types(unquote(module_name)) + + type = + Enum.find(types, fn {declaration, {type_name, _, _}} -> + declaration == :type && type_name == unquote(type_name) + end) + + assert type, + "expected the module #{unquote(module_name)} to have a public type named #{unquote(type_name)}" + + {:type, type} = type + + {:"::", _, [_, type_definition]} = Code.Typespec.type_to_quoted(type) + + actual_type_definition = Macro.to_string(type_definition) + + if is_list(unquote(expected_type_definition)) do + if actual_type_definition in unquote(expected_type_definition) do + assert true + else + # we know this will fail at this point, but we're using it to provide a nice failure message + assert actual_type_definition == hd(unquote(expected_type_definition)) + end + else + assert actual_type_definition == unquote(expected_type_definition) + end + end + end + + describe "the Form module" do + @tag task_id: 1 + test "has documentation" do + expected_moduledoc = """ + A collection of loosely related functions helpful for filling out various forms at the city office. + """ + + assert_moduledoc(expected_moduledoc) + end + end + + describe "blanks/1" do + @tag task_id: 2 + test "returns a string with Xs of a given length" do + assert Form.blanks(5) == "XXXXX" + end + + @tag task_id: 2 + test "returns an empty string when given length is 0" do + assert Form.blanks(0) == "" + end + + @tag task_id: 2 + test "has documentation" do + expected_doc = """ + Generates a string of a given length. + + This string can be used to fill out a form field that is supposed to have no value. + Such fields cannot be left empty because a malicious third party could fill them out with false data. + """ + + assert_doc({:blanks, 1}, expected_doc) + end + + @tag task_id: 2 + test "has a correct spec" do + assert_spec({:blanks, 1}, ["n :: non_neg_integer()", "non_neg_integer()"], "String.t()") + end + end + + describe "letters/1" do + @tag task_id: 3 + test "returns a list of upcase letters" do + assert Form.letters("Sao Paulo") == ["S", "A", "O", " ", "P", "A", "U", "L", "O"] + end + + @tag task_id: 3 + test "returns an empty list when given an empty string" do + assert Form.letters("") == [] + end + + @tag task_id: 3 + test "has documentation" do + expected_doc = """ + Splits the string into a list of uppercase letters. + + This is needed for form fields that don't offer a single input for the whole string, + but instead require splitting the string into a predefined number of single-letter inputs. + """ + + assert_doc({:letters, 1}, expected_doc) + end + + @tag task_id: 3 + test "has a typespec" do + assert_spec({:letters, 1}, ["word :: String.t()", "String.t()"], "[String.t()]") + end + end + + describe "check_length/2" do + @tag task_id: 4 + test "returns :ok is value is below max length" do + assert Form.check_length("Ruiz", 6) == :ok + end + + @tag task_id: 4 + test "returns :ok is value is of exactly max length" do + assert Form.check_length("Martinez-Cooper", 15) == :ok + end + + @tag task_id: 4 + test "returns an error tuple with the difference between max length and actual length" do + assert Form.check_length("Martinez-Campbell", 10) == {:error, 7} + end + + @tag task_id: 4 + test "has documentation" do + expected_doc = """ + Checks if the value has no more than the maximum allowed number of letters. + + This is needed to check that the values of fields do not exceed the maximum allowed length. + It also tells you by how much the value exceeds the maximum. + """ + + assert_doc({:check_length, 2}, expected_doc) + end + + @tag task_id: 4 + test "has a typespec" do + assert_spec( + {:check_length, 2}, + ["word :: String.t(), length :: non_neg_integer()", "String.t(), non_neg_integer()"], + ":ok | {:error, pos_integer()}" + ) + end + end + + describe "custom types in the Form module" do + @tag task_id: 5 + test "has a custom 'address_map' type" do + expected_type_definitions = [ + "%{street: String.t(), postal_code: String.t(), city: String.t()}", + "%{street: String.t(), city: String.t(), postal_code: String.t()}", + "%{postal_code: String.t(), street: String.t(), city: String.t()}", + "%{postal_code: String.t(), city: String.t(), street: String.t()}", + "%{city: String.t(), street: String.t(), postal_code: String.t()}", + "%{city: String.t(), postal_code: String.t(), street: String.t()}" + ] + + assert_type({Form, :address_map}, expected_type_definitions) + end + + @tag task_id: 5 + test "has a custom 'address_tuple' type with named arguments" do + expected_type_definition = + "{street :: String.t(), postal_code :: String.t(), city :: String.t()}" + + assert_type({Form, :address_tuple}, expected_type_definition) + end + + @tag task_id: 5 + test "has a custom 'address' type that is a union of 'address_map' and 'address_tuple'" do + expected_type_definitions = [ + "address_map() | address_tuple()", + "address_tuple() | address_map()" + ] + + assert_type({Form, :address}, expected_type_definitions) + end + end + + describe "format_address/1" do + @tag task_id: 6 + test "accepts a map" do + input = %{ + street: "Wiejska 4/6/8", + postal_code: "00-902", + city: "Warsaw" + } + + result = """ + WIEJSKA 4/6/8 + 00-902 WARSAW + """ + + assert Form.format_address(input) == result + end + + @tag task_id: 6 + test "accepts a 3 string tuple" do + result = """ + PLATZ DER REPUBLIK 1 + 11011 BERLIN + """ + + assert Form.format_address({"Platz der Republik 1", "11011", "Berlin"}) == result + end + + @tag task_id: 6 + test "has documentation" do + expected_doc = """ + Formats the address as an uppercase multiline string. + """ + + assert_doc({:format_address, 1}, expected_doc) + end + + @tag task_id: 6 + test "has a typespec" do + assert_spec({:format_address, 1}, ["address :: address()", "address()"], "String.t()") + end + end +end diff --git a/elixir/city-office/test/test_helper.exs b/elixir/city-office/test/test_helper.exs new file mode 100644 index 0000000..e8677a3 --- /dev/null +++ b/elixir/city-office/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true, seed: 0) diff --git a/elixir/collatz-conjecture/.exercism/config.json b/elixir/collatz-conjecture/.exercism/config.json new file mode 100644 index 0000000..c55238e --- /dev/null +++ b/elixir/collatz-conjecture/.exercism/config.json @@ -0,0 +1,26 @@ +{ + "authors": [ + "Tuxified" + ], + "contributors": [ + "angelikatyborska", + "Cohen-Carlisle", + "devonestes", + "neenjaw", + "sotojuan" + ], + "files": { + "solution": [ + "lib/collatz_conjecture.ex" + ], + "test": [ + "test/collatz_conjecture_test.exs" + ], + "example": [ + ".meta/example.ex" + ] + }, + "blurb": "Calculate the number of steps to reach 1 using the Collatz conjecture.", + "source": "An unsolved problem in mathematics named after mathematician Lothar Collatz", + "source_url": "https://en.wikipedia.org/wiki/3x_%2B_1_problem" +} diff --git a/elixir/collatz-conjecture/.exercism/metadata.json b/elixir/collatz-conjecture/.exercism/metadata.json new file mode 100644 index 0000000..e981e38 --- /dev/null +++ b/elixir/collatz-conjecture/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"collatz-conjecture","id":"af0a52fbaf7d40e8b28828aff758c922","url":"https://exercism.org/tracks/elixir/exercises/collatz-conjecture","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/collatz-conjecture/.formatter.exs b/elixir/collatz-conjecture/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/collatz-conjecture/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/collatz-conjecture/.gitignore b/elixir/collatz-conjecture/.gitignore new file mode 100644 index 0000000..a47ad81 --- /dev/null +++ b/elixir/collatz-conjecture/.gitignore @@ -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"). +collatz_conjecture-*.tar + diff --git a/elixir/collatz-conjecture/HELP.md b/elixir/collatz-conjecture/HELP.md new file mode 100644 index 0000000..a95ba02 --- /dev/null +++ b/elixir/collatz-conjecture/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/collatz_conjecture.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/collatz-conjecture/README.md b/elixir/collatz-conjecture/README.md new file mode 100644 index 0000000..bc8e3af --- /dev/null +++ b/elixir/collatz-conjecture/README.md @@ -0,0 +1,50 @@ +# Collatz Conjecture + +Welcome to Collatz Conjecture on Exercism's Elixir Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +The Collatz Conjecture or 3x+1 problem can be summarized as follows: + +Take any positive integer n. If n is even, divide n by 2 to get n / 2. If n is +odd, multiply n by 3 and add 1 to get 3n + 1. Repeat the process indefinitely. +The conjecture states that no matter which number you start with, you will +always reach 1 eventually. + +Given a number n, return the number of steps required to reach 1. + +## Examples + +Starting with n = 12, the steps would be as follows: + +0. 12 +1. 6 +2. 3 +3. 10 +4. 5 +5. 16 +6. 8 +7. 4 +8. 2 +9. 1 + +Resulting in 9 steps. So for input n = 12, the return value would be 9. + +## Source + +### Created by + +- @Tuxified + +### Contributed to by + +- @angelikatyborska +- @Cohen-Carlisle +- @devonestes +- @neenjaw +- @sotojuan + +### Based on + +An unsolved problem in mathematics named after mathematician Lothar Collatz - https://en.wikipedia.org/wiki/3x_%2B_1_problem \ No newline at end of file diff --git a/elixir/collatz-conjecture/lib/collatz_conjecture.ex b/elixir/collatz-conjecture/lib/collatz_conjecture.ex new file mode 100644 index 0000000..0ff5ecc --- /dev/null +++ b/elixir/collatz-conjecture/lib/collatz_conjecture.ex @@ -0,0 +1,20 @@ +defmodule CollatzConjecture do + @doc """ + calc/1 takes an integer and returns the number of steps required to get the + number to 1 when following the rules: + - if number is odd, multiply with 3 and add 1 + - if number is even, divide by 2 + """ + @spec calc(input :: pos_integer()) :: non_neg_integer() + + def calc(input) when is_integer(input) do + collatz(input, 0) + end + + defp collatz(1, steps), do: steps + + defp collatz(input, steps) when input > 0 and rem(input, 2) == 0, + do: collatz(div(input, 2), steps + 1) + + defp collatz(input, steps) when input > 0, do: collatz(3 * input + 1, steps + 1) +end diff --git a/elixir/collatz-conjecture/mix.exs b/elixir/collatz-conjecture/mix.exs new file mode 100644 index 0000000..4d9e251 --- /dev/null +++ b/elixir/collatz-conjecture/mix.exs @@ -0,0 +1,28 @@ +defmodule CollatzConjecture.MixProject do + use Mix.Project + + def project do + [ + app: :collatz_conjecture, + 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 diff --git a/elixir/collatz-conjecture/test/collatz_conjecture_test.exs b/elixir/collatz-conjecture/test/collatz_conjecture_test.exs new file mode 100644 index 0000000..0c7cedc --- /dev/null +++ b/elixir/collatz-conjecture/test/collatz_conjecture_test.exs @@ -0,0 +1,39 @@ +defmodule CollatzConjectureTest do + use ExUnit.Case + + test "zero steps for one" do + assert CollatzConjecture.calc(1) == 0 + end + + test "zero is an error" do + assert_raise FunctionClauseError, fn -> CollatzConjecture.calc(0) end + end + + test "divide if even" do + assert CollatzConjecture.calc(16) == 4 + end + + test "even and odd steps" do + assert CollatzConjecture.calc(12) == 9 + end + + test "Large number of even and odd steps" do + assert CollatzConjecture.calc(1_000_000) == 152 + end + + test "start with odd step" do + assert CollatzConjecture.calc(21) == 7 + end + + test "more steps than starting number" do + assert CollatzConjecture.calc(7) == 16 + end + + test "negative value is an error " do + assert_raise FunctionClauseError, fn -> CollatzConjecture.calc(-15) end + end + + test "string as input value is an error " do + assert_raise FunctionClauseError, fn -> CollatzConjecture.calc("fubar") end + end +end diff --git a/elixir/collatz-conjecture/test/test_helper.exs b/elixir/collatz-conjecture/test/test_helper.exs new file mode 100644 index 0000000..35fc5bf --- /dev/null +++ b/elixir/collatz-conjecture/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true) diff --git a/elixir/dna-encoding/.exercism/config.json b/elixir/dna-encoding/.exercism/config.json new file mode 100644 index 0000000..c5039fb --- /dev/null +++ b/elixir/dna-encoding/.exercism/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "neenjaw" + ], + "contributors": [ + "angelikatyborska", + "NobbZ" + ], + "files": { + "solution": [ + "lib/dna.ex" + ], + "test": [ + "test/dna_test.exs" + ], + "exemplar": [ + ".meta/exemplar.ex" + ] + }, + "language_versions": ">=1.10", + "blurb": "Learn about bitstrings and tail call recursion by encoding DNA sequences as binary data." +} diff --git a/elixir/dna-encoding/.exercism/metadata.json b/elixir/dna-encoding/.exercism/metadata.json new file mode 100644 index 0000000..a965de4 --- /dev/null +++ b/elixir/dna-encoding/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"dna-encoding","id":"b36d8706517343e99bd8187edf2b3be6","url":"https://exercism.org/tracks/elixir/exercises/dna-encoding","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/dna-encoding/.formatter.exs b/elixir/dna-encoding/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/dna-encoding/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/dna-encoding/.gitignore b/elixir/dna-encoding/.gitignore new file mode 100644 index 0000000..3793de1 --- /dev/null +++ b/elixir/dna-encoding/.gitignore @@ -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"). +bitstrings-*.tar + diff --git a/elixir/dna-encoding/HELP.md b/elixir/dna-encoding/HELP.md new file mode 100644 index 0000000..04a7d9f --- /dev/null +++ b/elixir/dna-encoding/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/dna.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/dna-encoding/HINTS.md b/elixir/dna-encoding/HINTS.md new file mode 100644 index 0000000..b154595 --- /dev/null +++ b/elixir/dna-encoding/HINTS.md @@ -0,0 +1,45 @@ +# Hints + +## General + +- Use `?` to work with the character [code points][codepoint]. +- `\s` can be used to represent a space. +- Use [integer binary notation][integer-literal] for working with the codes. +- Try to use the tail call recursion strategy. + +## 1. Encode nucleic acid to binary value + +- This function needs to map one integer to another. +- Making use of multiple clause functions may make this easier by breaking it down. + +## 2. Decode the binary value to the nucleic acid + +- This function is the opposite of part 1's function. +- Making use of multiple clause functions may make this easier by breaking it down. + +## 3. Encode a DNA charlist + +- Create a recursive function which takes a code point from the charlist and recursively builds the bitstring result. +- Remember, a [charlist][charlist] is a list of [integer code points][codepoint]. +- You can get the first and remaining items from a list using a build in [`Kernel` module][kernel] function. +- You can also pattern match on a list using the [`[head | tail]`][list] notation. +- Use multiple clause functions to separate the base case from the recursive cases. +- Do not forget to specify the types of bitstring segments using the `::` operator. + +## 4. Decode a DNA bitstring + +- Create a recursive function which [matches the first 4 bits][bitstring-matching] from the [bitstring][bitstring] and recursively builds the [charlist][charlist] result. +- Remember the [bitstring special form][bitstring-form] can be used for matching on bitstrings. +- Do not forget to specify the types of bitstring segments using the `::` operator. +- You will need to reverse the accumulator at the end. Write a private tail-recursive `reverse` function to do that and use it in the base-case of the `decode` function. + +[integer-literal]: https://hexdocs.pm/elixir/master/syntax-reference.html#integers-in-other-bases-and-unicode-code-points +[codepoint]: https://elixir-lang.org/getting-started/binaries-strings-and-char-lists.html#unicode-and-code-points +[charlist]: https://elixir-lang.org/getting-started/binaries-strings-and-char-lists.html#charlists +[bitstring]: https://elixir-lang.org/getting-started/binaries-strings-and-char-lists.html#bitstrings +[bitstring-form]: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#%3C%3C%3E%3E/1 +[bitstring-matching]: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#%3C%3C%3E%3E/1-binary-bitstring-matching +[type-operator]: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#::/2 +[recursion-tco]: https://en.wikipedia.org/wiki/Tail_call +[list]: https://hexdocs.pm/elixir/List.html#content +[kernel]: https://hexdocs.pm/elixir/Kernel.html#functions \ No newline at end of file diff --git a/elixir/dna-encoding/README.md b/elixir/dna-encoding/README.md new file mode 100644 index 0000000..e554a40 --- /dev/null +++ b/elixir/dna-encoding/README.md @@ -0,0 +1,149 @@ +# DNA Encoding + +Welcome to DNA Encoding 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 + +## Bitstrings + +Working with binary data is an important concept in any language, and Elixir provides an elegant syntax to write, match, and construct binary data. + +In Elixir, binary data is referred to as the bitstring type. The binary data*type* (not to be confused with binary data in general) is a specific form of a bitstring, which we will discuss in a later exercise. + +Bitstring literals are defined using the bitstring special form `<<>>`. When defining a bitstring literal, it is defined in segments. Each segment has a value and type, separated by the `::` operator. The type specifies how many bits will be used to encode the value. If the value of the segment overflows the capacity of the segment's type, it will be truncated from the left. + +```elixir +# This defines a bitstring with three segments of a single bit each +<<0::1, 1::1, 0::1>> == <<0::size(1), 1::size(1), 0::size(1)>> +# => true +<<0::1, 1::1, 0::1>> == <<2::size(3)>> +# => true +<<2::1>> == <<0::1>> +# => true because of value overflow +``` + +When writing binary integer literals, we can write them directly in base-2 notation by prefixing the literal with `0b`. + +```elixir +value = 0b11111011011 = 2011 +``` + +By default, bitstrings are displayed in chunks of 8 bits (a byte). + +``` +<> +# => <<251, 3::size(3)>> +``` + +### Constructing + +We can combine bitstrings stored in variables using the special form: + +```elixir +first = <<0b110::3>> +second = <<0b001::3>> +combined = <> +# => <<49::size(6)>> +``` + +### Pattern matching + +Pattern matching can also be done to obtain the value from within the special form: + +```elixir +<> = <<0b01101001::8>> +value == 0b0110 +# => true +``` + +## Tail Call Recursion + +When [recursing][exercism-recursion] through enumerables (lists, bitstrings, strings), there are often two concerns: + +- how much memory is required to store the trail of recursive function calls +- how to build the solution efficiently + +To deal with these concerns an _accumulator_ may be used. + +An accumulator is a variable that is passed along in addition to the data. It is used to pass the current state of the function's execution, from function call to function call, until the _base case_ is reached. In the base case, the accumulator is used to return the final value of the recursive function call. + +Accumulators should be initialized by the function's author, not the function's user. To achieve this, declare two functions - a public function that takes just the necessary data as arguments and initializes the accumulator, and a private function that also takes an accumulator. In Elixir, it is a common pattern to prefix the private function's name with `do_`. + +```elixir +# Count the length of a list without an accumulator +def count([]), do: 0 +def count([_head | tail]), do: 1 + count(tail) + +# Count the length of a list with an accumulator +def count(list), do: do_count(list, 0) + +defp do_count([], count), do: count +defp do_count([_head | tail], count), do: do_count(tail, count + 1) +``` + +The usage of an accumulator allows us to turn recursive functions into _tail-recursive_ functions. A function is tail-recursive if the _last_ thing executed by the function is a call to itself. + +[exercism-recursion]: https://exercism.org/tracks/elixir/concepts/recursion + +## Instructions + +In your DNA research lab, you have been working through various ways to compress your research data to save storage space. One teammate suggests converting the DNA data to a binary representation: + +| Nucleic Acid | Code | +| ------------ | ------ | +| a space | `0000` | +| A | `0001` | +| C | `0010` | +| G | `0100` | +| T | `1000` | + +You ponder this, as it will potentially halve the required data storage costs, but at the expense of human readability. You decide to write a module to encode and decode your data to benchmark your savings. + +## 1. Encode nucleic acid to binary value + +Implement `encode_nucleotide/1` to accept the code point for the nucleic acid and return the integer value of the encoded code. + +```elixir +DNA.encode_nucleotide(?A) +# => 0b0001 +``` + +## 2. Decode the binary value to the nucleic acid + +Implement `decode_nucleotide/1` to accept the integer value of the encoded code and return the code point for the nucleic acid. + +```elixir +DNA.decode_nucleotide(0b0001) +# => ?A +``` + +## 3. Encode a DNA charlist + +Implement `encode/1` to accept a charlist representing nucleic acids and gaps and return a bitstring of the encoded data. + +```elixir +DNA.encode('AC GT') +# => <<18, 4, 8::size(4)>> +``` + +## 4. Decode a DNA bitstring + +Implement `decode/1` to accept a bitstring representing nucleic acids and gaps and return the decoded data as a charlist. + +```elixir +DNA.decode(<<132, 2, 1::size(4)>>) +# => 'TG CA' +``` + +## Source + +### Created by + +- @neenjaw + +### Contributed to by + +- @angelikatyborska +- @NobbZ \ No newline at end of file diff --git a/elixir/dna-encoding/lib/dna.ex b/elixir/dna-encoding/lib/dna.ex new file mode 100644 index 0000000..42986c0 --- /dev/null +++ b/elixir/dna-encoding/lib/dna.ex @@ -0,0 +1,17 @@ +defmodule DNA do + def encode_nucleotide(code_point) do + # Please implement the encode_nucleotide/1 function + end + + def decode_nucleotide(encoded_code) do + # Please implement the decode_nucleotide/1 function + end + + def encode(dna) do + # Please implement the encode/1 function + end + + def decode(dna) do + # Please implement the decode/1 function + end +end diff --git a/elixir/dna-encoding/mix.exs b/elixir/dna-encoding/mix.exs new file mode 100644 index 0000000..b322446 --- /dev/null +++ b/elixir/dna-encoding/mix.exs @@ -0,0 +1,28 @@ +defmodule DNA.MixProject do + use Mix.Project + + def project do + [ + app: :dna, + 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 diff --git a/elixir/dna-encoding/test/dna_test.exs b/elixir/dna-encoding/test/dna_test.exs new file mode 100644 index 0000000..92b3d2b --- /dev/null +++ b/elixir/dna-encoding/test/dna_test.exs @@ -0,0 +1,71 @@ +defmodule DNATest do + use ExUnit.Case + + describe "encode to 4-bit encoding" do + @tag task_id: 1 + test "?\\s to 0b0000", do: assert(DNA.encode_nucleotide(?\s) == 0b0000) + @tag task_id: 1 + test "?A to 0b0001", do: assert(DNA.encode_nucleotide(?A) == 0b0001) + @tag task_id: 1 + test "?C to 0b0010", do: assert(DNA.encode_nucleotide(?C) == 0b0010) + @tag task_id: 1 + test "?G to 0b0100", do: assert(DNA.encode_nucleotide(?G) == 0b0100) + @tag task_id: 1 + test "?T to 0b1000", do: assert(DNA.encode_nucleotide(?T) == 0b1000) + end + + describe "decode to code point" do + @tag task_id: 2 + test "0b0000 to ?\\s", do: assert(DNA.decode_nucleotide(0b0000) == ?\s) + @tag task_id: 2 + test "0b0001 to ?A", do: assert(DNA.decode_nucleotide(0b0001) == ?A) + @tag task_id: 2 + test "0b0010 to ?C", do: assert(DNA.decode_nucleotide(0b0010) == ?C) + @tag task_id: 2 + test "0b0100 to ?G", do: assert(DNA.decode_nucleotide(0b0100) == ?G) + @tag task_id: 2 + test "0b1000 to ?T", do: assert(DNA.decode_nucleotide(0b1000) == ?T) + end + + describe "encoding" do + @tag task_id: 3 + test "' '", do: assert(DNA.encode(' ') == <<0b0000::4>>) + @tag task_id: 3 + test "'A'", do: assert(DNA.encode('A') == <<0b0001::4>>) + @tag task_id: 3 + test "'C'", do: assert(DNA.encode('C') == <<0b0010::4>>) + @tag task_id: 3 + test "'G'", do: assert(DNA.encode('G') == <<0b0100::4>>) + @tag task_id: 3 + test "'T'", do: assert(DNA.encode('T') == <<0b1000::4>>) + + @tag task_id: 3 + test "' ACGT'", + do: assert(DNA.encode(' ACGT') == <<0b0000::4, 0b0001::4, 0b0010::4, 0b0100::4, 0b1000::4>>) + + @tag task_id: 3 + test "'TGCA '", + do: assert(DNA.encode('TGCA ') == <<0b1000::4, 0b0100::4, 0b0010::4, 0b0001::4, 0b0000::4>>) + end + + describe "decoding" do + @tag task_id: 4 + test "' '", do: assert(DNA.decode(<<0b0000::4>>) == ' ') + @tag task_id: 4 + test "'A'", do: assert(DNA.decode(<<0b0001::4>>) == 'A') + @tag task_id: 4 + test "'C'", do: assert(DNA.decode(<<0b0010::4>>) == 'C') + @tag task_id: 4 + test "'G'", do: assert(DNA.decode(<<0b0100::4>>) == 'G') + @tag task_id: 4 + test "'T'", do: assert(DNA.decode(<<0b1000::4>>) == 'T') + + @tag task_id: 4 + test "' ACGT'", + do: assert(DNA.decode(<<0b0000::4, 0b0001::4, 0b0010::4, 0b0100::4, 0b1000::4>>) == ' ACGT') + + @tag task_id: 4 + test "'TGCA '", + do: assert(DNA.decode(<<0b1000::4, 0b0100::4, 0b0010::4, 0b0001::4, 0b0000::4>>) == 'TGCA ') + end +end diff --git a/elixir/dna-encoding/test/test_helper.exs b/elixir/dna-encoding/test/test_helper.exs new file mode 100644 index 0000000..e8677a3 --- /dev/null +++ b/elixir/dna-encoding/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true, seed: 0) diff --git a/elixir/guessing-game/.exercism/config.json b/elixir/guessing-game/.exercism/config.json new file mode 100644 index 0000000..a76dc72 --- /dev/null +++ b/elixir/guessing-game/.exercism/config.json @@ -0,0 +1,24 @@ +{ + "authors": [ + "neenjaw" + ], + "contributors": [ + "angelikatyborska" + ], + "files": { + "solution": [ + "lib/guessing_game.ex" + ], + "test": [ + "test/guessing_game_test.exs" + ], + "exemplar": [ + ".meta/exemplar.ex" + ] + }, + "language_versions": ">=1.10", + "forked_from": [ + "fsharp/guessing-game" + ], + "blurb": "Learn about multiple clause functions, guards, and default arguments by implementing a simple game in which the player needs to guess a secret number." +} diff --git a/elixir/guessing-game/.exercism/metadata.json b/elixir/guessing-game/.exercism/metadata.json new file mode 100644 index 0000000..86db4ac --- /dev/null +++ b/elixir/guessing-game/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"guessing-game","id":"f70876e9539441d6b6ec0053b3682657","url":"https://exercism.org/tracks/elixir/exercises/guessing-game","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/guessing-game/.formatter.exs b/elixir/guessing-game/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/guessing-game/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/guessing-game/.gitignore b/elixir/guessing-game/.gitignore new file mode 100644 index 0000000..1c705bc --- /dev/null +++ b/elixir/guessing-game/.gitignore @@ -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"). +multiple_clause_functions-*.tar + diff --git a/elixir/guessing-game/HELP.md b/elixir/guessing-game/HELP.md new file mode 100644 index 0000000..b4e790e --- /dev/null +++ b/elixir/guessing-game/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/guessing_game.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/guessing-game/HINTS.md b/elixir/guessing-game/HINTS.md new file mode 100644 index 0000000..f608af6 --- /dev/null +++ b/elixir/guessing-game/HINTS.md @@ -0,0 +1,33 @@ +# Hints + +## General + +- In Elixir's ['Getting Started Guide'][guide] there is a nice refresher about named functions. + +## 1. Make the response when the guess matches the secret number + +- You can use a [guard][guard] to check if the numbers are the same with `===/2`. + +## 2. Make the response when the guess is greater than the secret number + +- You can add a [function clause][multiple-fn-clauses] and [guards][guard] to check if the guess is greater `>/2` than the secret number. + +## 3. Make the response when the guess is less than the secret number + +- You can add a [function clause][multiple-fn-clauses] and [guards][guard] to check if the guess is less than ` 100, do: "Not that big..." +``` + +[kernel-guards]: https://hexdocs.pm/elixir/master/Kernel.html#guards + +## Instructions + +You are creating a trivial online game where a friend can guess a secret number. You want to give some feedback, but not give away the answer with a guess. You need to devise a function to provide different responses depending on how the guess relates to the secret number. + +| Condition | Response | +| ------------------------------------------------------------- | -------------- | +| When the guess matches the secret number | "Correct" | +| When the guess is one more or one less than the secret number | "So close" | +| When the guess is greater than the secret number | "Too high" | +| When the guess is less than the secret number | "Too low" | +| When a guess isn't made | "Make a guess" | + +All guesses and secret numbers are integer numbers. + +## 1. Make the response when the guess matches the secret number + +Implement the `compare/2` function which takes two arguments, `secret_number` and `guess`, which are both integers. + +```elixir +GuessingGame.compare(5, 5) +# => "Correct" +``` + +## 2. Make the response when the guess is greater than the secret number + +Modify the `compare` function to respond to guesses that are higher than the secret number. + +```elixir +GuessingGame.compare(5, 8) +# => "Too high" +``` + +## 3. Make the response when the guess is less than the secret number + +Modify the `compare` function to respond to guesses that are lower than the secret number. + +```elixir +GuessingGame.compare(5, 2) +# => "Too low" +``` + +## 4. Make the responses when the guess is one more or one less than the secret number + +Modify the `compare` function to respond to guesses that are close to the secret number. + +```elixir +GuessingGame.compare(5, 6) +# => "So close" +GuessingGame.compare(5, 4) +# => "So close" +``` + +## 5. Make the response when there is no guess + +Modify the `compare` function to respond to a lack of guess. + +```elixir +GuessingGame.compare(5) +# => "Make a guess" + +GuessingGame.compare(5, :no_guess) +# => "Make a guess" +``` + +## Source + +### Created by + +- @neenjaw + +### Contributed to by + +- @angelikatyborska \ No newline at end of file diff --git a/elixir/guessing-game/lib/guessing_game.ex b/elixir/guessing-game/lib/guessing_game.ex new file mode 100644 index 0000000..07f0bbe --- /dev/null +++ b/elixir/guessing-game/lib/guessing_game.ex @@ -0,0 +1,12 @@ +defmodule GuessingGame do + + def compare(_secret_number, :no_guess \\ :no_guess), do: "Make a guess" + + def compare(secret_number, guess) when secret_number == guess, do: "Correct" + + def compare(secret_number, guess) when abs(guess-secret_number) == 1, do: "So close" + + def compare(secret_number, guess) when guess > secret_number, do: "Too high" + + def compare(secret_number, guess) when guess < secret_number, do: "Too low" +end diff --git a/elixir/guessing-game/mix.exs b/elixir/guessing-game/mix.exs new file mode 100644 index 0000000..6911be3 --- /dev/null +++ b/elixir/guessing-game/mix.exs @@ -0,0 +1,28 @@ +defmodule GuessingGame.MixProject do + use Mix.Project + + def project do + [ + app: :guessing_game, + 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 diff --git a/elixir/guessing-game/test/guessing_game_test.exs b/elixir/guessing-game/test/guessing_game_test.exs new file mode 100644 index 0000000..2afcf34 --- /dev/null +++ b/elixir/guessing-game/test/guessing_game_test.exs @@ -0,0 +1,38 @@ +defmodule GuessingGameTest do + use ExUnit.Case + + @tag task_id: 1 + test "correct when the guessed number equals secret" do + assert GuessingGame.compare(7, 7) == "Correct" + end + + @tag task_id: 2 + test "too high when guessed number is greater than the secret" do + assert GuessingGame.compare(9, 18) == "Too high" + end + + @tag task_id: 3 + test "too low when guessed number is less than the secret" do + assert GuessingGame.compare(42, 30) == "Too low" + end + + @tag task_id: 4 + test "so close when guess differs from secret by -1" do + assert GuessingGame.compare(64, 63) == "So close" + end + + @tag task_id: 4 + test "so close when guess differs from secret by +1" do + assert GuessingGame.compare(52, 53) == "So close" + end + + @tag task_id: 5 + test "when no guess is supplied, ask the player to make a guess" do + assert GuessingGame.compare(15) == "Make a guess" + end + + @tag task_id: 5 + test "when the atom :no_guess is supplied, ask the player to make a guess" do + assert GuessingGame.compare(16, :no_guess) == "Make a guess" + end +end diff --git a/elixir/guessing-game/test/test_helper.exs b/elixir/guessing-game/test/test_helper.exs new file mode 100644 index 0000000..e8677a3 --- /dev/null +++ b/elixir/guessing-game/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true, seed: 0) diff --git a/elixir/kitchen-calculator/.exercism/config.json b/elixir/kitchen-calculator/.exercism/config.json new file mode 100644 index 0000000..957060f --- /dev/null +++ b/elixir/kitchen-calculator/.exercism/config.json @@ -0,0 +1,21 @@ +{ + "authors": [ + "neenjaw" + ], + "contributors": [ + "angelikatyborska" + ], + "files": { + "solution": [ + "lib/kitchen_calculator.ex" + ], + "test": [ + "test/kitchen_calculator_test.exs" + ], + "exemplar": [ + ".meta/exemplar.ex" + ] + }, + "language_versions": ">=1.10", + "blurb": "Learn about tuples and pattern matching by converting common US baking measurements to the metric system." +} diff --git a/elixir/kitchen-calculator/.exercism/metadata.json b/elixir/kitchen-calculator/.exercism/metadata.json new file mode 100644 index 0000000..d5ca60d --- /dev/null +++ b/elixir/kitchen-calculator/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"kitchen-calculator","id":"fba1265584b9449783f6074ce0c8ceb8","url":"https://exercism.org/tracks/elixir/exercises/kitchen-calculator","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/kitchen-calculator/.formatter.exs b/elixir/kitchen-calculator/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/kitchen-calculator/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/kitchen-calculator/.gitignore b/elixir/kitchen-calculator/.gitignore new file mode 100644 index 0000000..c803e51 --- /dev/null +++ b/elixir/kitchen-calculator/.gitignore @@ -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"). +tuples-*.tar + diff --git a/elixir/kitchen-calculator/HELP.md b/elixir/kitchen-calculator/HELP.md new file mode 100644 index 0000000..5e586e3 --- /dev/null +++ b/elixir/kitchen-calculator/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/kitchen_calculator.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/kitchen-calculator/HINTS.md b/elixir/kitchen-calculator/HINTS.md new file mode 100644 index 0000000..1855aa0 --- /dev/null +++ b/elixir/kitchen-calculator/HINTS.md @@ -0,0 +1,30 @@ +# Hints + +## General + +- [Tuples][tuple-module] are data structures which are arranged in contiguous memory and can hold any data-type. +- Atoms may be used to denote finite states, as this exercise uses `:cup`, `:fluid_ounce`, `:teaspoon`, `:tablespoon`, `:milliliter` to denote the units used. +- You may use [`Kernel`][elem] or [`Tuple`][tuple-module] functions or pattern matching to manipulate the tuples. + +## 1. Get the numeric component from a volume-pair + +- Consider using [a `Kernel` module function][elem] to return the volume-pair's numeric component. + +## 2. Convert the volume-pair to milliliters + +- Use [multiple clause functions][multi-clause] and [pattern matching][pattern-matching] to reduce conditional control flow logic. +- Implement the function for all units to milliliters, including milliliters to milliliters. + +## 3. Convert the milliliter volume-pair to another unit + +- Use [multiple clause functions][multi-clause] and [pattern matching][pattern-matching] to reduce conditional control flow logic. +- Implement the function for all units to milliliters, including milliliters to milliliters. + +## 4. Convert from any unit to any unit + +- Reuse the functions already created to perform the conversion in the `convert/2` function. + +[elem]: https://hexdocs.pm/elixir/Kernel.html#elem/2 +[multi-clause]: https://elixir-lang.org/getting-started/modules-and-functions.html#named-functions +[tuple-module]: https://hexdocs.pm/elixir/Tuple.html +[pattern-matching]: https://medium.com/rebirth-delivery/how-to-use-elixir-pattern-matched-functions-arguments-a793733acc6d \ No newline at end of file diff --git a/elixir/kitchen-calculator/README.md b/elixir/kitchen-calculator/README.md new file mode 100644 index 0000000..6e1df7e --- /dev/null +++ b/elixir/kitchen-calculator/README.md @@ -0,0 +1,143 @@ +# Kitchen Calculator + +Welcome to Kitchen Calculator 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 + +## Tuples + +In Elixir, a tuple is a data structure which organizes data, holding a fixed number of items of any type, but without explicit names for each element. Tuples are often used in Elixir for memory read-intensive operations, since read-access of an element is a constant-time operation. They are not usually used when elements may need to be added/removed dynamically because rather than modifying the existing tuple, a new tuple is created which requires memory to be allocated upfront. + +In practice, tuples are created in Elixir using curly braces. Elements in a tuple can be individually accessed using the `elem/2` function using 0-based indexing: + +```elixir +empty_tuple = {} +one_element_tuple = {1} +multiple_element_tuple = {1, :a, "hello"} + +elem(multiple_element_tuple, 2) +# => "hello" +``` + +### Tuples as grouped information + +Tuples are often used in practice to represent grouped information. + +```elixir +Float.ratio(0.25) +# => {1, 4} indicating the numerator and denominator of the fraction ¼ +``` + +## Pattern Matching + +The use of pattern matching is dominant in assertive, idiomatic Elixir code. You might recall that `=/2` is described as a match operator rather than as an assignment operator. When using the match operator, if the pattern on the left matches the right, any variables on the left are bound, and the value of the right side is returned. A `MatchError` is raised if there is no match. + +```elixir +2 = 2 +# => 2 +# Literals can be matched if they are the same + +2 = 3 +# => ** (MatchError) no match of right hand side value: 3 + +{_, denominator} = Float.ratio(0.25) +# => {1, 4} +# the variable `denominator` is bound to the value 4 +``` + +Remember, matches occur from the right side to the left side. + +In the last example if we don't need a variable in a pattern match, we can discard it by referencing `_`. Any variable starting with an `_` is not tracked by the runtime. + +### Pattern matching in named functions + +Pattern matching is also a useful tool when creating multiple function clauses. Pattern matching can be used on the functions' arguments which then determines which function clause to invoke -- starting from the top of the file down until the first match. Variables may be bound in a function head and used in the function body. + +```elixir +defmodule Example do + def named_function(:a = variable_a) do + {variable_a, 1} + end + + def named_function(:b = variable_b) do + {variable_b, 2} + end +end + +Example.named_function(:a) +# => {:a, 1} + +Example.named_function(:b) +# => {:b, 2} + +Example.named_function(:c) +# => ** (FunctionClauseError) no function clause matching in Example.named_function/1 +``` + +## Instructions + +While preparing to bake cookies for your friends, you have found that you have to convert some of the measurements used in the recipe. Being only familiar with the metric system, you need to come up with a way to convert common US baking measurements to milliliters (mL) for your own ease. + +Use this conversion chart for your solution: + +| Unit to convert | volume | in milliliters (mL) | +| --------------- | ------ | ------------------- | +| mL | 1 | 1 | +| US cup | 1 | 240 | +| US fluid ounce | 1 | 30 | +| US teaspoon | 1 | 5 | +| US tablespoon | 1 | 15 | + +Being a talented programmer in training, you decide to use milliliters as a transition unit to facilitate the conversion from any unit listed to any other (even itself). + +## 1. Get the numeric component from a volume-pair + +Implement the `KitchenCalculator.get_volume/1` function. Given a volume-pair tuple, it should return just the numeric component. + +```elixir +KitchenCalculator.get_volume({:cup, 2.0}) +# => 2.0 +``` + +## 2. Convert the volume-pair to milliliters + +Implement the `KitchenCalculator.to_milliliter/1` function. Given a volume-pair tuple, it should convert the volume to milliliters using the conversion chart. + +Use multiple function clauses and pattern matching to create the functions for each unit. The atoms used to denote each unit are: `:cup`, `:fluid_ounce`, `:teaspoon`, `:tablespoon`, `:milliliter`. Return the result of the conversion wrapped in a tuple. + +```elixir +KitchenCalculator.to_milliliter({:cup, 2.5}) +# => {:milliliter, 600.0} +``` + +## 3. Convert the milliliter volume-pair to another unit + +Implement the `KitchenCalculator.from_milliliter/2` function. Given a volume-pair tuple and the desired unit, it should convert the volume to the desired unit using the conversion chart. + +Use multiple function clauses and pattern matching to create the functions for each unit. The atoms used to denote each unit are: `:cup`, `:fluid_ounce`, `:teaspoon`, `:tablespoon`, `:milliliter` + +```elixir +KitchenCalculator.from_milliliter({:milliliter, 1320.0}, :cup) +# => {:cup, 5.5} +``` + +## 4. Convert from any unit to any unit + +Implement the `KitchenCalculator.convert/2` function. Given a volume-pair tuple and the desired unit, it should convert the given volume to the desired unit. + +```elixir +KitchenCalculator.convert({:teaspoon, 9.0}, :tablespoon) +# => {:tablespoon, 3.0} +``` + +## Source + +### Created by + +- @neenjaw + +### Contributed to by + +- @angelikatyborska \ No newline at end of file diff --git a/elixir/kitchen-calculator/lib/kitchen_calculator.ex b/elixir/kitchen-calculator/lib/kitchen_calculator.ex new file mode 100644 index 0000000..ba7bd68 --- /dev/null +++ b/elixir/kitchen-calculator/lib/kitchen_calculator.ex @@ -0,0 +1,31 @@ +defmodule KitchenCalculator do + def get_volume(volume_pair) do + elem(volume_pair, 1) + end + + def to_milliliter(volume_pair) do + volume = get_volume(volume_pair) + case elem(volume_pair, 0) do + :milliliter -> volume + :fluid_ounce -> 30 * volume + :cup -> 240 * volume + :teaspoon -> 5 * volume + :tablespoon -> 15 * volume + _ -> -1 + end + end + + def from_milliliter({:milliliter, volume}, unit) do + case unit do + :cup -> volume / 240 + :fluid_ounce -> volume / 30 + :teaspoon -> volume / 5 + :tablespoon -> volume / 15 + _ -> volume + end + end + + def convert({unit1, volume}, unit2) do + from_milliliter({:milliliter, to_milliliter({unit1, volume})}, unit2) + end +end diff --git a/elixir/kitchen-calculator/mix.exs b/elixir/kitchen-calculator/mix.exs new file mode 100644 index 0000000..f27d87b --- /dev/null +++ b/elixir/kitchen-calculator/mix.exs @@ -0,0 +1,28 @@ +defmodule KitchenCalculator.MixProject do + use Mix.Project + + def project do + [ + app: :kitchen_calculator, + 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 diff --git a/elixir/kitchen-calculator/test/kitchen_calculator_test.exs b/elixir/kitchen-calculator/test/kitchen_calculator_test.exs new file mode 100644 index 0000000..331cbb4 --- /dev/null +++ b/elixir/kitchen-calculator/test/kitchen_calculator_test.exs @@ -0,0 +1,109 @@ +defmodule KitchenCalculatorTest do + use ExUnit.Case + + describe "get volume from tuple pair" do + @tag task_id: 1 + test "get cups" do + assert KitchenCalculator.get_volume({:cup, 1}) == 1 + end + + @tag task_id: 1 + test "get fluid ounces" do + assert KitchenCalculator.get_volume({:fluid_ounce, 2}) == 2 + end + + @tag task_id: 1 + test "get teaspoons" do + assert KitchenCalculator.get_volume({:teaspoon, 3}) == 3 + end + + @tag task_id: 1 + test "get tablespoons" do + assert KitchenCalculator.get_volume({:tablespoon, 4}) == 4 + end + + @tag task_id: 1 + test "get milliliters" do + assert KitchenCalculator.get_volume({:milliliter, 5}) == 5 + end + end + + describe "convert to milliliters from" do + @tag task_id: 2 + test "milliliters" do + assert KitchenCalculator.to_milliliter({:milliliter, 3}) == {:milliliter, 3} + end + + @tag task_id: 2 + test "cups" do + assert KitchenCalculator.to_milliliter({:cup, 3}) == {:milliliter, 720} + end + + @tag task_id: 2 + test "fluid ounces" do + assert KitchenCalculator.to_milliliter({:fluid_ounce, 100}) == {:milliliter, 3000} + end + + @tag task_id: 2 + test "teaspoon" do + assert KitchenCalculator.to_milliliter({:teaspoon, 3}) == {:milliliter, 15} + end + + @tag task_id: 2 + test "tablespoon" do + assert KitchenCalculator.to_milliliter({:tablespoon, 3}) == {:milliliter, 45} + end + end + + describe "convert from milliliters to" do + @tag task_id: 3 + test "milliliters" do + assert KitchenCalculator.from_milliliter({:milliliter, 4}, :milliliter) == {:milliliter, 4} + end + + @tag task_id: 3 + test "cups" do + assert KitchenCalculator.from_milliliter({:milliliter, 840}, :cup) == {:cup, 3.5} + end + + @tag task_id: 3 + test "fluid ounces" do + assert KitchenCalculator.from_milliliter({:milliliter, 4522.5}, :fluid_ounce) == + {:fluid_ounce, 150.75} + end + + @tag task_id: 3 + test "teaspoon" do + assert KitchenCalculator.from_milliliter({:milliliter, 61.25}, :teaspoon) == + {:teaspoon, 12.25} + end + + @tag task_id: 3 + test "tablespoon" do + assert KitchenCalculator.from_milliliter({:milliliter, 71.25}, :tablespoon) == + {:tablespoon, 4.75} + end + end + + describe "convert from x to y:" do + @tag task_id: 4 + test "teaspoon to tablespoon" do + assert KitchenCalculator.convert({:teaspoon, 15}, :tablespoon) == {:tablespoon, 5} + end + + @tag task_id: 4 + test "cups to fluid ounces" do + assert KitchenCalculator.convert({:cup, 4}, :fluid_ounce) == {:fluid_ounce, 32} + end + + @tag task_id: 4 + test "fluid ounces to teaspoons" do + assert KitchenCalculator.convert({:fluid_ounce, 4}, :teaspoon) == {:teaspoon, 24} + end + + @tag task_id: 4 + test "tablespoons to cups" do + assert KitchenCalculator.convert({:tablespoon, 320}, :cup) == {:cup, 20} + end + end +end diff --git a/elixir/kitchen-calculator/test/test_helper.exs b/elixir/kitchen-calculator/test/test_helper.exs new file mode 100644 index 0000000..e8677a3 --- /dev/null +++ b/elixir/kitchen-calculator/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true, seed: 0) diff --git a/elixir/leap/.exercism/config.json b/elixir/leap/.exercism/config.json new file mode 100644 index 0000000..ff02c3f --- /dev/null +++ b/elixir/leap/.exercism/config.json @@ -0,0 +1,35 @@ +{ + "authors": [ + "rubysolo" + ], + "contributors": [ + "angelikatyborska", + "Cohen-Carlisle", + "dalexj", + "devonestes", + "glennular", + "jinyeow", + "korbin", + "kytrinyx", + "lpil", + "neenjaw", + "parkerl", + "sotojuan", + "Teapane", + "waiting-for-dev" + ], + "files": { + "solution": [ + "lib/year.ex" + ], + "test": [ + "test/year_test.exs" + ], + "example": [ + ".meta/example.ex" + ] + }, + "blurb": "Given a year, report if it is a leap year.", + "source": "JavaRanch Cattle Drive, exercise 3", + "source_url": "http://www.javaranch.com/leap.jsp" +} diff --git a/elixir/leap/.exercism/metadata.json b/elixir/leap/.exercism/metadata.json new file mode 100644 index 0000000..0d0b436 --- /dev/null +++ b/elixir/leap/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"leap","id":"0621ad4832e546b6b1a1e5e07af0b3f0","url":"https://exercism.org/tracks/elixir/exercises/leap","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/leap/.formatter.exs b/elixir/leap/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/leap/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/leap/.gitignore b/elixir/leap/.gitignore new file mode 100644 index 0000000..baae2d4 --- /dev/null +++ b/elixir/leap/.gitignore @@ -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"). +leap-*.tar + diff --git a/elixir/leap/HELP.md b/elixir/leap/HELP.md new file mode 100644 index 0000000..b7b94c7 --- /dev/null +++ b/elixir/leap/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/year.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/leap/README.md b/elixir/leap/README.md new file mode 100644 index 0000000..ce08158 --- /dev/null +++ b/elixir/leap/README.md @@ -0,0 +1,56 @@ +# Leap + +Welcome to Leap on Exercism's Elixir Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +Given a year, report if it is a leap year. + +The tricky thing here is that a leap year in the Gregorian calendar occurs: + +```text +on every year that is evenly divisible by 4 + except every year that is evenly divisible by 100 + unless the year is also evenly divisible by 400 +``` + +For example, 1997 is not a leap year, but 1996 is. 1900 is not a leap +year, but 2000 is. + +## Notes + +Though our exercise adopts some very simple rules, there is more to +learn! + +For a delightful, four minute explanation of the whole leap year +phenomenon, go watch [this youtube video][video]. + +[video]: http://www.youtube.com/watch?v=xX96xng7sAE + +## Source + +### Created by + +- @rubysolo + +### Contributed to by + +- @angelikatyborska +- @Cohen-Carlisle +- @dalexj +- @devonestes +- @glennular +- @jinyeow +- @korbin +- @kytrinyx +- @lpil +- @neenjaw +- @parkerl +- @sotojuan +- @Teapane +- @waiting-for-dev + +### Based on + +JavaRanch Cattle Drive, exercise 3 - http://www.javaranch.com/leap.jsp \ No newline at end of file diff --git a/elixir/leap/lib/year.ex b/elixir/leap/lib/year.ex new file mode 100644 index 0000000..7fc7a5c --- /dev/null +++ b/elixir/leap/lib/year.ex @@ -0,0 +1,16 @@ +defmodule Year do + @doc """ + Returns whether 'year' is a leap year. + + A leap year occurs: + + on every year that is evenly divisible by 4 + except every year that is evenly divisible by 100 + unless the year is also evenly divisible by 400 + """ + @spec leap_year?(non_neg_integer) :: boolean + def leap_year?(year) when rem(year, 400) == 0, do: true + def leap_year?(year) when rem(year, 100) == 0, do: false + def leap_year?(year) when rem(year, 4) == 0, do: true + def leap_year?(_year), do: false +end diff --git a/elixir/leap/mix.exs b/elixir/leap/mix.exs new file mode 100644 index 0000000..a74f3c9 --- /dev/null +++ b/elixir/leap/mix.exs @@ -0,0 +1,28 @@ +defmodule Year.MixProject do + use Mix.Project + + def project do + [ + app: :year, + 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 diff --git a/elixir/leap/test/test_helper.exs b/elixir/leap/test/test_helper.exs new file mode 100644 index 0000000..35fc5bf --- /dev/null +++ b/elixir/leap/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true) diff --git a/elixir/leap/test/year_test.exs b/elixir/leap/test/year_test.exs new file mode 100644 index 0000000..621c1c4 --- /dev/null +++ b/elixir/leap/test/year_test.exs @@ -0,0 +1,48 @@ +defmodule YearTest do + use ExUnit.Case + + # @tag :pending + test "year not divisible by 4 is common year" do + refute Year.leap_year?(2015) + end + + @tag :pending + test "year divisible by 2, not divisible by 4 is common year" do + refute Year.leap_year?(1970) + end + + @tag :pending + test "year divisible by 4, not divisible by 100 is leap year" do + assert Year.leap_year?(1996) + end + + @tag :pending + test "year divisible by 4 and 5 is still a leap year" do + assert Year.leap_year?(1960) + end + + @tag :pending + test "year divisible by 100, not divisible by 400 is common year" do + refute Year.leap_year?(2100) + end + + @tag :pending + test "year divisible by 100 but not by 3 is still not a leap year" do + refute Year.leap_year?(1900) + end + + @tag :pending + test "year divisible by 400 is leap year" do + assert Year.leap_year?(2000) + end + + @tag :pending + test "year divisible by 400 but not by 125 is still a leap year" do + assert Year.leap_year?(2400) + end + + @tag :pending + test "year divisible by 200, not divisible by 400 in common year" do + refute Year.leap_year?(1800) + end +end diff --git a/elixir/library-fees/.exercism/config.json b/elixir/library-fees/.exercism/config.json new file mode 100644 index 0000000..060a2ec --- /dev/null +++ b/elixir/library-fees/.exercism/config.json @@ -0,0 +1,21 @@ +{ + "authors": [ + "angelikatyborska" + ], + "contributors": [ + "neenjaw" + ], + "files": { + "solution": [ + "lib/library_fees.ex" + ], + "test": [ + "test/library_fees_test.exs" + ], + "exemplar": [ + ".meta/exemplar.ex" + ] + }, + "language_versions": ">=1.10", + "blurb": "Learn about dates and time by calculating late fees for the local library." +} diff --git a/elixir/library-fees/.exercism/metadata.json b/elixir/library-fees/.exercism/metadata.json new file mode 100644 index 0000000..7bf4027 --- /dev/null +++ b/elixir/library-fees/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"library-fees","id":"f919bcf7474041d6b5dd2b3990192dd2","url":"https://exercism.org/tracks/elixir/exercises/library-fees","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/library-fees/.formatter.exs b/elixir/library-fees/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/library-fees/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/library-fees/.gitignore b/elixir/library-fees/.gitignore new file mode 100644 index 0000000..4abee35 --- /dev/null +++ b/elixir/library-fees/.gitignore @@ -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"). +match_binary-*.tar + diff --git a/elixir/library-fees/HELP.md b/elixir/library-fees/HELP.md new file mode 100644 index 0000000..a9b6b73 --- /dev/null +++ b/elixir/library-fees/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/library_fees.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/library-fees/HINTS.md b/elixir/library-fees/HINTS.md new file mode 100644 index 0000000..018b039 --- /dev/null +++ b/elixir/library-fees/HINTS.md @@ -0,0 +1,47 @@ +# Hints + +## General + +- Review the functions available in the [`NaiveDateTime` module][naive-date-time], the [`Date` module][date], and the [`Time` module][time]. + +## 1. Parse the stored datetimes + +- There is a [built-in function][naive-date-time-from-iso8601] that parses an ISO8601 datetime string and returns a `NaiveDateTime` struct. + +## 2. Determine if a book was checked out before noon + +- You can define a `Time` literal using the [`~T` sigil][time-sigil]. +- There is a [built-in function][naive-date-time-to-time] that changes a `NaiveDateTime` struct to a `Time` struct. +- There is a [built-in function][time-compare] that checks which one of two `Time` structs is bigger. + +## 3. Calculate the return date + +- A day has `24 * 60 * 60` seconds. +- There is a [built-in function][naive-date-time-add] that adds a given number of seconds to a `NaiveDateTime` struct. +- There is a [built-in function][naive-date-time-to-date] that changes a `NaiveDateTime` struct to a `Date` struct. + +## 4. Determine how late the return of the book was + +- There is a [built-in function][naive-date-time-to-date] that changes a `NaiveDateTime` struct to a `Date` struct. +- There is a [built-in function][date-diff] that calculates the difference in days between two `Date` structs. + +## 5. Determine if the book was returned on a Monday + +- There is a [built-in function][naive-date-time-to-date] that changes a `NaiveDateTime` struct to a `Date` struct. +- There is a [built-in function][date-day-of-week] that returns the day of week for a given `Date` struct. + +## 6. Calculate the late fee + +- Combine together all of the functions that you defined in previous steps. + +[naive-date-time]: https://hexdocs.pm/elixir/NaiveDateTime.html +[time]: https://hexdocs.pm/elixir/Time.html +[date]: https://hexdocs.pm/elixir/Date.html +[naive-date-time-from-iso8601]: https://hexdocs.pm/elixir/NaiveDateTime.html#from_iso8601!/2 +[naive-date-time-to-time]: https://hexdocs.pm/elixir/NaiveDateTime.html#to_time/1 +[naive-date-time-to-date]: https://hexdocs.pm/elixir/NaiveDateTime.html#to_date/1 +[naive-date-time-add]: https://hexdocs.pm/elixir/NaiveDateTime.html#add/3 +[time-sigil]: https://hexdocs.pm/elixir/Kernel.html#sigil_T/2 +[time-compare]: https://hexdocs.pm/elixir/Time.html#compare/2 +[date-diff]: https://hexdocs.pm/elixir/Date.html#diff/2 +[date-day-of-week]: https://hexdocs.pm/elixir/Date.html#day_of_week/2 \ No newline at end of file diff --git a/elixir/library-fees/README.md b/elixir/library-fees/README.md new file mode 100644 index 0000000..4d5bbb5 --- /dev/null +++ b/elixir/library-fees/README.md @@ -0,0 +1,124 @@ +# Library Fees + +Welcome to Library Fees 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 + +## Dates and Time + +Elixir's standard library offers 4 different modules for working with dates and time, each with its own struct. + +- The `Date` module. A `Date` struct can be created with the `~D` sigil. + + ```elixir + ~D[2021-01-01] + ``` + +- The `Time` module. A `Time` struct can be created with the `~T` sigil. + + ```elixir + ~T[12:00:00] + ``` + +- The `NaiveDateTime` module for datetimes without a timezone. A `NaiveDateTime` struct can be created with the `~N` sigil. + + ```elixir + ~N[2021-01-01 12:00:00] + ``` + +- The `DateTime` module for datetimes with a timezone. Using this module for timezones other than UTC requires an external dependency, a timezone database. + +### Comparisons + +To compare dates or times to one another, look for a `compare` or `diff` function in the corresponding module. Comparison operators such as `==`, `>`, and `<` _seem_ to work, but they don't do a correct semantic comparison for those structs. + +## Instructions + +Your librarian friend has asked you to extend her library software to automatically calculate late fees. +Her current system stores the exact date and time of a book checkout as an [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) datetime string. +She runs a local library in a small town in Ghana, which uses the GMT timezone (UTC +0), doesn't use daylight saving time, and doesn't need to worry about other timezones. + +## 1. Parse the stored datetimes + +Implement the `LibraryFees.datetime_from_string/1` function. It should take an ISO8601 datetime string as an argument, and return a `NaiveDateTime` struct. + +```elixir +LibraryFees.datetime_from_string("2021-01-01T13:30:45Z") +# => ~N[2021-01-01 13:30:45] +``` + +## 2. Determine if a book was checked out before noon + +If a book was checked out before noon, the reader has 28 days to return it. If it was checked out at or after noon, it's 29 days. + +Implement the `LibraryFees.before_noon?/1` function. It should take a `NaiveDateTime` struct and return a boolean. + +```elixir +LibraryFees.before_noon?(~N[2021-01-12 08:23:03]) +# => true +``` + +## 3. Calculate the return date + +Based on the checkout datetime, calculate the return date. + +Implement the `LibraryFees.return_date/1` function. It should take a `NaiveDateTime` struct and return a `Date` struct, either 28 or 29 days later. + +```elixir +LibraryFees.return_date(~N[2020-11-28 15:55:33]) +# => ~D[2020-12-27] +``` + +## 4. Determine how late the return of the book was + +The library has a flat rate for late returns. To be able to calculate the fee, we need to know how many days after the return date the book was actually returned. + +Implement the `LibraryFees.days_late/2` function. It should take a `Date` struct - the planned return datetime, and a `NaiveDateTime` struct - the actual return datetime. + +If the actual return date is on an earlier or the same day as the planned return datetime, the function should return 0. Otherwise, the function should return the difference between those two dates in days. + +The library tracks both the date and time of the actual return of the book for statistical purposes, but doesn't use the time when calculating late fees. + +```elixir +LibraryFees.days_late(~D[2020-12-27], ~N[2021-01-03 09:23:36]) +# => 7 +``` + +## 5. Determine if the book was returned on a Monday + +The library has a special offer for returning books on Mondays. + +Implement the `LibraryFees.monday?/1` function. It should take a `NaiveDateTime` struct and return a boolean. + +```elixir +LibraryFees.monday?(~N[2021-01-03 13:30:45Z]) +# => false +``` + +## 6. Calculate the late fee + +Implement the `LibraryFees.calculate_late_fee/3` function. It should take three arguments - two ISO8601 datetime strings, checkout datetime and actual return datetime, and the late fee for one day. It should return the total late fee according to how late the actual return of the book was. + +Include the special Monday offer. If you return the book on Monday, your late fee is 50% off, rounded down. + +```elixir +# Sunday, 7 days late +LibraryFees.calculate_late_fee("2020-11-28T15:55:33Z", "2021-01-03T13:30:45Z", 100) +# => 700 + +# one day later, Monday, 8 days late +LibraryFees.calculate_late_fee("2020-11-28T15:55:33Z", "2021-01-04T09:02:11Z", 100) +# => 400 +``` + +## Source + +### Created by + +- @angelikatyborska + +### Contributed to by + +- @neenjaw \ No newline at end of file diff --git a/elixir/library-fees/lib/library_fees.ex b/elixir/library-fees/lib/library_fees.ex new file mode 100644 index 0000000..c33da49 --- /dev/null +++ b/elixir/library-fees/lib/library_fees.ex @@ -0,0 +1,39 @@ +defmodule LibraryFees do + def datetime_from_string(string) do + {:ok, dt} = NaiveDateTime.from_iso8601(string) + dt + end + + def before_noon?(datetime) do + datetime.hour < 12 + end + + def return_date(checkout_datetime) do + dt = NaiveDateTime.to_date(checkout_datetime) + case before_noon?(checkout_datetime) do + true -> Date.add(dt, 28) + _ -> Date.add(dt, 29) + end + end + + def days_late(planned_return_date, actual_return_datetime) do + actual_return_datetime + |> Date.diff(planned_return_date) + |> max(0) + end + + def monday?(datetime) do + Date.day_of_week(NaiveDateTime.to_date(datetime)) == 1 + end + + def calculate_late_fee(checkout, return, rate) do + checkout_datetime = datetime_from_string(checkout) + return_datetime = datetime_from_string(return) + raw_fee = days_late(return_date(checkout_datetime), return_datetime) * rate + if monday?(return_datetime) do + floor(raw_fee * 0.5) + else + raw_fee + end + end +end diff --git a/elixir/library-fees/mix.exs b/elixir/library-fees/mix.exs new file mode 100644 index 0000000..3a7e722 --- /dev/null +++ b/elixir/library-fees/mix.exs @@ -0,0 +1,28 @@ +defmodule CaptainsLog.MixProject do + use Mix.Project + + def project do + [ + app: :library_fees, + 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 diff --git a/elixir/library-fees/test/library_fees_test.exs b/elixir/library-fees/test/library_fees_test.exs new file mode 100644 index 0000000..b752777 --- /dev/null +++ b/elixir/library-fees/test/library_fees_test.exs @@ -0,0 +1,171 @@ +defmodule LibraryFeesTest do + use ExUnit.Case + + describe "datetime_from_string/1" do + @tag task_id: 1 + test "returns NaiveDateTime" do + result = LibraryFees.datetime_from_string("2021-01-01T12:00:00Z") + assert result.__struct__ == NaiveDateTime + end + + @tag task_id: 1 + test "parses an ISO8601 string" do + result = LibraryFees.datetime_from_string("2019-12-24T13:15:45Z") + assert result == ~N[2019-12-24 13:15:45Z] + end + end + + describe "before_noon?/1" do + @tag task_id: 2 + test "returns true if the given NaiveDateTime is before 12:00" do + assert LibraryFees.before_noon?(~N[2020-06-06 11:59:59Z]) == true + end + + @tag task_id: 2 + test "returns false if the given NaiveDateTime is after 12:00" do + assert LibraryFees.before_noon?(~N[2021-01-03 12:01:01Z]) == false + end + + @tag task_id: 2 + test "returns false if the given NaiveDateTime is exactly at 12:00" do + assert LibraryFees.before_noon?(~N[2018-11-17 12:00:00Z]) == false + end + end + + describe "return_date/1" do + @tag task_id: 3 + test "adds 28 days if the given NaiveDateTime is before 12:00" do + result = LibraryFees.return_date(~N[2020-02-14 11:59:59Z]) + assert result == ~D[2020-03-13] + end + + @tag task_id: 3 + test "adds 29 days if the given NaiveDateTime is after 12:00" do + result = LibraryFees.return_date(~N[2021-01-03 12:01:01Z]) + assert result == ~D[2021-02-01] + end + + @tag task_id: 3 + test "adds 29 days if the given NaiveDateTime is exactly at 12:00" do + result = LibraryFees.return_date(~N[2018-12-01 12:00:00Z]) + assert result == ~D[2018-12-30] + end + end + + describe "days_late/2" do + @tag task_id: 4 + test "returns 0 when identical datetimes" do + result = LibraryFees.days_late(~D[2021-02-01], ~N[2021-02-01 12:00:00Z]) + assert result == 0 + end + + @tag task_id: 4 + test "returns 0 when identical dates, but different times" do + result = LibraryFees.days_late(~D[2019-03-11], ~N[2019-03-11 12:00:00Z]) + assert result == 0 + end + + @tag task_id: 4 + test "returns 0 when planned return date is later than actual return date" do + result = LibraryFees.days_late(~D[2020-12-03], ~N[2020-11-29 16:00:00Z]) + assert result == 0 + end + + @tag task_id: 4 + test "returns date difference in numbers of days when planned return date is earlier than actual return date" do + result = LibraryFees.days_late(~D[2020-06-12], ~N[2020-06-21 16:00:00Z]) + assert result == 9 + end + + @tag task_id: 4 + test "a new day starts at midnight" do + result = LibraryFees.days_late(~D[2020-06-12], ~N[2020-06-12 23:59:59Z]) + assert result == 0 + + result = LibraryFees.days_late(~D[2020-06-12], ~N[2020-06-13 00:00:00Z]) + assert result == 1 + end + end + + describe "monday?" do + @tag task_id: 5 + test "2021-02-01 was a Monday" do + assert LibraryFees.monday?(~N[2021-02-01 14:01:00Z]) == true + end + + @tag task_id: 5 + test "2020-03-16 was a Monday" do + assert LibraryFees.monday?(~N[2020-03-16 09:23:52Z]) == true + end + + @tag task_id: 5 + test "2020-04-22 was a Monday" do + assert LibraryFees.monday?(~N[2019-04-22 15:44:03Z]) == true + end + + @tag task_id: 5 + test "2021-02-02 was a Tuesday" do + assert LibraryFees.monday?(~N[2021-02-02 15:07:00Z]) == false + end + + @tag task_id: 5 + test "2020-03-14 was a Friday" do + assert LibraryFees.monday?(~N[2020-03-14 08:54:51Z]) == false + end + + @tag task_id: 5 + test "2019-04-28 was a Sunday" do + assert LibraryFees.monday?(~N[2019-04-28 11:37:12Z]) == false + end + end + + describe "calculate_late_fee/2" do + @tag task_id: 6 + test "returns 0 if the book was returned less than 28 days after a morning checkout" do + result = LibraryFees.calculate_late_fee("2018-11-01T09:00:00Z", "2018-11-13T14:12:00Z", 123) + assert result == 0 + end + + @tag task_id: 6 + test "returns 0 if the book was returned exactly 28 days after a morning checkout" do + result = LibraryFees.calculate_late_fee("2018-11-01T09:00:00Z", "2018-11-29T14:12:00Z", 123) + assert result == 0 + end + + @tag task_id: 6 + test "returns the rate for one day if the book was returned exactly 29 days after a morning checkout" do + result = LibraryFees.calculate_late_fee("2018-11-01T09:00:00Z", "2018-11-30T14:12:00Z", 320) + assert result == 320 + end + + @tag task_id: 6 + test "returns 0 if the book was returned less than 29 days after an afternoon checkout" do + result = LibraryFees.calculate_late_fee("2019-05-01T16:12:00Z", "2019-05-17T14:32:45Z", 400) + assert result == 0 + end + + @tag task_id: 6 + test "returns 0 if the book was returned exactly 29 days after an afternoon checkout" do + result = LibraryFees.calculate_late_fee("2019-05-01T16:12:00Z", "2019-05-30T14:32:45Z", 313) + assert result == 0 + end + + @tag task_id: 6 + test "returns the rate for one day if the book was returned exactly 30 days after an afternoon checkout" do + result = LibraryFees.calculate_late_fee("2019-05-01T16:12:00Z", "2019-05-31T14:32:45Z", 234) + assert result == 234 + end + + @tag task_id: 6 + test "multiplies the number of days late by the rate for one day" do + result = LibraryFees.calculate_late_fee("2021-01-01T08:00:00Z", "2021-02-13T08:00:00Z", 111) + assert result == 111 * 15 + end + + @tag task_id: 6 + test "late fees are 50% off (rounded down) when the book is returned on a Monday" do + result = LibraryFees.calculate_late_fee("2021-01-01T08:00:00Z", "2021-02-15T08:00:00Z", 111) + assert result == trunc(111 * 17 * 0.5) + end + end +end diff --git a/elixir/library-fees/test/test_helper.exs b/elixir/library-fees/test/test_helper.exs new file mode 100644 index 0000000..e8677a3 --- /dev/null +++ b/elixir/library-fees/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true, seed: 0) diff --git a/elixir/log-level/.exercism/config.json b/elixir/log-level/.exercism/config.json new file mode 100644 index 0000000..bd25fce --- /dev/null +++ b/elixir/log-level/.exercism/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "neenjaw" + ], + "files": { + "solution": [ + "lib/log_level.ex" + ], + "test": [ + "test/log_level_test.exs" + ], + "exemplar": [ + ".meta/exemplar.ex" + ] + }, + "language_versions": ">=1.10", + "forked_from": [ + "csharp/logs-logs-logs" + ], + "icon": "log-levels", + "blurb": "Learn about atoms and the cond conditional expression by aggregating application logs." +} diff --git a/elixir/log-level/.exercism/metadata.json b/elixir/log-level/.exercism/metadata.json new file mode 100644 index 0000000..3abcab6 --- /dev/null +++ b/elixir/log-level/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"log-level","id":"cfabdd7d8b3045aa9515e5fcc87ffaf6","url":"https://exercism.org/tracks/elixir/exercises/log-level","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/log-level/.formatter.exs b/elixir/log-level/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/log-level/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/log-level/.gitignore b/elixir/log-level/.gitignore new file mode 100644 index 0000000..cd58551 --- /dev/null +++ b/elixir/log-level/.gitignore @@ -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"). +cond-*.tar + diff --git a/elixir/log-level/HELP.md b/elixir/log-level/HELP.md new file mode 100644 index 0000000..95de5b9 --- /dev/null +++ b/elixir/log-level/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/log_level.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/log-level/HINTS.md b/elixir/log-level/HINTS.md new file mode 100644 index 0000000..74d5508 --- /dev/null +++ b/elixir/log-level/HINTS.md @@ -0,0 +1,20 @@ +# Hints + +## General + +- The [atom type is described here][atom]. + +## 1. Return the logging code label + +- You can use the [`cond/1` special form][cond] to elegantly handle the various log codes. +- You can use [equality operators][equality] to compare integers for strict type equality. +- There is a [way to specify a default branch][cond] in a cond expression that can be used to catch unspecified cases. + +## 2. Send an alert + +- You can use the [`cond/1` special form][cond] to decide if an alert should be sent. +- You can use [equality operators][equality] to compare atoms for equality. + +[equality]: https://elixir-lang.org/getting-started/basic-operators.html +[atom]: https://elixir-lang.org/getting-started/basic-types.html#atoms +[cond]: https://elixir-lang.org/getting-started/case-cond-and-if.html#cond \ No newline at end of file diff --git a/elixir/log-level/README.md b/elixir/log-level/README.md new file mode 100644 index 0000000..79b426e --- /dev/null +++ b/elixir/log-level/README.md @@ -0,0 +1,82 @@ +# Log Level + +Welcome to Log Level 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 + +## Atoms + +Elixir's `atom` type represents a fixed constant. An atom's value is simply its own name. This gives us a type-safe way to interact with data. Atoms can be defined as follows: + +```elixir +# All atoms are preceded with a ':' then follow with alphanumeric snake-cased characters +variable = :an_atom +``` + +_Atoms_ are internally represented by an integer in a lookup table, which are set automatically. It is not possible to change this internal value. + +## Cond + +Often, we want to write code that can branch based on a condition. While there are many ways to do this in Elixir, one of the simplest ways is using `cond/1`. + +At its simplest, `cond` follows the first path that evaluates to `true` with one or more branches: + +```elixir +cond do + x > 10 -> :this_might_be_the_way + y < 7 -> :or_that_might_be_the_way + true -> :this_is_the_default_way +end +``` + +If no path evaluates to `true`, an error is raised by the runtime. + +## Instructions + +You are running a system that consists of a few applications producing many logs. You want to write a small program that will aggregate those logs and give them labels according to their severity level. All applications in your system use the same log codes, but some of the legacy applications don't support all the codes. + +| Log code | Log label | Supported in legacy apps? | +| -------- | --------- | ------------------------- | +| 0 | trace | no | +| 1 | debug | yes | +| 2 | info | yes | +| 3 | warning | yes | +| 4 | error | yes | +| 5 | fatal | no | +| ? | unknown | - | + +## 1. Return the logging code label + +Implement the `LogLevel.to_label/2` function. It should take an integer code and a boolean flag telling you if the log comes from a legacy app, and return the label of a log line as an atom. Unknown log codes and codes unsupported in a legacy app should return an _unknown_ label. + +```elixir +LogLevel.to_label(0, false) +# => :trace + +LogLevel.to_label(0, true) +# => :unknown +``` + +## 2. Send an alert + +Somebody has to be notified when unexpected things happen. + +Implement the `LogLevel.alert_recipient/2` function to determine to whom the alert needs to be sent. The function should take an integer code and a boolean flag telling you if the log comes from a legacy app, and return the name of the recipient as an atom. + +If the log label is _error_ or _fatal_, send the alert to the _ops_ team. If you receive a log with an _unknown_ label from a legacy system, send the alert to the _dev1_ team, other unknown labels should be sent to the _dev2_ team. All other log labels can be safely ignored. + +```elixir +LogLevel.alert_recipient(-1, true) +# => :dev1 + +LogLevel.alert_recipient(0, false) +# => false +``` + +## Source + +### Created by + +- @neenjaw \ No newline at end of file diff --git a/elixir/log-level/lib/log_level.ex b/elixir/log-level/lib/log_level.ex new file mode 100644 index 0000000..4b3c62e --- /dev/null +++ b/elixir/log-level/lib/log_level.ex @@ -0,0 +1,23 @@ +defmodule LogLevel do + def to_label(level, legacy?) do + cond do + level==0 && !legacy? -> :trace + level==1 && legacy? -> :debug + level==2 && legacy? -> :info + level==3 && legacy? -> :warning + level==4 && legacy? -> :error + level==5 && !legacy? -> :fatal + true -> :unknown + end + end + + def alert_recipient(level, legacy?) do + lbl = to_label(level, legacy?) + cond do + lbl == :fatal || lbl == :error -> :ops + lbl == :unknown && legacy? -> :dev1 + lbl == :unknown -> :dev2 + true -> false + end + end +end diff --git a/elixir/log-level/mix.exs b/elixir/log-level/mix.exs new file mode 100644 index 0000000..46d643d --- /dev/null +++ b/elixir/log-level/mix.exs @@ -0,0 +1,28 @@ +defmodule LogLevel.MixProject do + use Mix.Project + + def project do + [ + app: :log_level, + 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 diff --git a/elixir/log-level/test/log_level_test.exs b/elixir/log-level/test/log_level_test.exs new file mode 100644 index 0000000..8060e10 --- /dev/null +++ b/elixir/log-level/test/log_level_test.exs @@ -0,0 +1,101 @@ +defmodule LogLevelTest do + use ExUnit.Case + + describe "LogLevel.to_label/2" do + @tag task_id: 1 + test "level 0 has label trace only in a non-legacy app" do + assert LogLevel.to_label(0, false) == :trace + assert LogLevel.to_label(0, true) == :unknown + end + + @tag task_id: 1 + test "level 1 has label debug" do + assert LogLevel.to_label(1, false) == :debug + assert LogLevel.to_label(1, true) == :debug + end + + @tag task_id: 1 + test "level 2 has label info" do + assert LogLevel.to_label(2, false) == :info + assert LogLevel.to_label(2, true) == :info + end + + @tag task_id: 1 + test "level 3 has label warning" do + assert LogLevel.to_label(3, false) == :warning + assert LogLevel.to_label(3, true) == :warning + end + + @tag task_id: 1 + test "level 4 has label error" do + assert LogLevel.to_label(4, false) == :error + assert LogLevel.to_label(4, true) == :error + end + + @tag task_id: 1 + test "level 5 has label fatal only in a non-legacy app" do + assert LogLevel.to_label(5, false) == :fatal + assert LogLevel.to_label(5, true) == :unknown + end + + @tag task_id: 1 + test "level 6 has label unknown" do + assert LogLevel.to_label(6, false) == :unknown + assert LogLevel.to_label(6, true) == :unknown + end + + @tag task_id: 1 + test "level -1 has label unknown" do + assert LogLevel.to_label(-1, false) == :unknown + assert LogLevel.to_label(-1, true) == :unknown + end + end + + describe "LogLevel.alert_recipient/2" do + @tag task_id: 2 + test "fatal code sends alert to ops" do + assert LogLevel.alert_recipient(5, false) == :ops + end + + @tag task_id: 2 + test "error code sends alert to ops" do + assert LogLevel.alert_recipient(4, false) == :ops + assert LogLevel.alert_recipient(4, true) == :ops + end + + @tag task_id: 2 + test "unknown code sends alert to dev team 1 for a legacy app" do + assert LogLevel.alert_recipient(6, true) == :dev1 + assert LogLevel.alert_recipient(0, true) == :dev1 + assert LogLevel.alert_recipient(5, true) == :dev1 + end + + @tag task_id: 2 + test "unknown code sends alert to dev team 2" do + assert LogLevel.alert_recipient(6, false) == :dev2 + end + + @tag task_id: 2 + test "trace code does not send alert" do + refute LogLevel.alert_recipient(0, false) + end + + @tag task_id: 2 + test "debug code does not send alert" do + refute LogLevel.alert_recipient(1, false) + refute LogLevel.alert_recipient(1, true) + end + + @tag task_id: 2 + test "info code does not send alert" do + refute LogLevel.alert_recipient(2, false) + refute LogLevel.alert_recipient(2, true) + end + + @tag task_id: 2 + test "warning code does not send alert" do + refute LogLevel.alert_recipient(3, false) + refute LogLevel.alert_recipient(3, true) + end + end +end diff --git a/elixir/log-level/test/test_helper.exs b/elixir/log-level/test/test_helper.exs new file mode 100644 index 0000000..e8677a3 --- /dev/null +++ b/elixir/log-level/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true, seed: 0) diff --git a/elixir/need-for-speed/.exercism/config.json b/elixir/need-for-speed/.exercism/config.json new file mode 100644 index 0000000..db08d82 --- /dev/null +++ b/elixir/need-for-speed/.exercism/config.json @@ -0,0 +1,28 @@ +{ + "authors": [ + "angelikatyborska" + ], + "contributors": [ + "neenjaw" + ], + "files": { + "solution": [ + "lib/need_for_speed.ex" + ], + "test": [ + "test/need_for_speed_test.exs" + ], + "exemplar": [ + ".meta/exemplar.ex" + ], + "editor": [ + "lib/need_for_speed/race.ex", + "lib/need_for_speed/remote_control_car.ex" + ] + }, + "language_versions": ">=1.10", + "forked_from": [ + "csharp/need-for-speed" + ], + "blurb": "Learn about reusing code with alias and import by racing remote controlled cars." +} diff --git a/elixir/need-for-speed/.exercism/metadata.json b/elixir/need-for-speed/.exercism/metadata.json new file mode 100644 index 0000000..eca8b41 --- /dev/null +++ b/elixir/need-for-speed/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"need-for-speed","id":"38ba42c7ad434333b67b6e7a59e671a7","url":"https://exercism.org/tracks/elixir/exercises/need-for-speed","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/need-for-speed/.formatter.exs b/elixir/need-for-speed/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/need-for-speed/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/need-for-speed/.gitignore b/elixir/need-for-speed/.gitignore new file mode 100644 index 0000000..b97fe0c --- /dev/null +++ b/elixir/need-for-speed/.gitignore @@ -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"). +structs-*.tar + diff --git a/elixir/need-for-speed/HELP.md b/elixir/need-for-speed/HELP.md new file mode 100644 index 0000000..af3d000 --- /dev/null +++ b/elixir/need-for-speed/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/need_for_speed.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/need-for-speed/HINTS.md b/elixir/need-for-speed/HINTS.md new file mode 100644 index 0000000..6e584c5 --- /dev/null +++ b/elixir/need-for-speed/HINTS.md @@ -0,0 +1,31 @@ +# Hints + +## General + +- Read about [`alias` and `import`][getting-started] in the Getting Started guide. +- Read about [module composition][elixir-school-module-composition] on elixirschool.com. + +## 1. Fix compilation error `Race.__struct__/0 is undefined` + +- An alias can be created with the [`alias`][alias] special form. + +## 2. Fix compilation error `Car.__struct__/0 is undefined` + +- An alias can be created with the [`alias`][alias] special form. +- The `alias` special form accepts an `:as` option. + +## 3. Fix compilation error `undefined function puts/1` + +- Functions can be imported with the [`import`][import] special form. +- The [`import`][import] special form accepts an `:only` option. Its value should be a keyword list with function name as keys and function arities as values. + +## 4. Fix compilation error `undefined function default_color/0` + +- Functions can be imported with the [`import`][import] special form. +- The [`import`][import] special form accepts an `:except` option. Its value should be a keyword list with function name as keys and function arities as values. + + +[alias]: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#alias/2 +[import]: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#import/2 +[elixir-school-module-composition]: https://elixirschool.com/en/lessons/basics/modules/#composition +[getting-started]: https://elixir-lang.org/getting-started/alias-require-and-import.html \ No newline at end of file diff --git a/elixir/need-for-speed/README.md b/elixir/need-for-speed/README.md new file mode 100644 index 0000000..c077a4b --- /dev/null +++ b/elixir/need-for-speed/README.md @@ -0,0 +1,71 @@ +# Need For Speed + +Welcome to Need For Speed 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 + +## Alias + +To share code between different Elixir modules within the same project, you need to reference the outside module by its full name. But what if that name is too long or confusing? + +The special form `alias` allows you to shorten or change the name by which you reference an outside module. When used without any arguments, it trims down the module name to its last segment, e.g. `MyApp.Logger.Settings` becomes `Settings`. A custom name can be specified with the `:as` option. + +Usually aliases are added at the beginning of the module definition. + +```elixir +defmodule Square do + alias Integer, as: I + + def area(a), do: I.pow(a, 2) +end +``` + +## Import + +The special form `import` allows you to use functions from an outside module without using the module's name. + +Importing a whole outside module might create conflicts with existing local functions. To avoid this, two options are available: `:except` and `:only`. Both expect a keyword list, where the key is the function name, and the value is the function's arity. + +Usually imports are added at the beginning of the module definition. + +```elixir +defmodule Square do + import Integer, only: [pow: 2] + + def area(a), do: pow(a, 2) +end +``` + +## Instructions + +That remote controlled car that you bought recently has turned into a whole new hobby. You have been organizing remote control car races. + +You were almost finished writing a program that would allow to run race simulations when your cat jumped at your keyboard and deleted a few lines of code. Now your program doesn't compile anymore... + +## 1. Fix compilation error `Race.__struct__/0 is undefined` + +Add an alias so that the module `NeedForSpeed.Race` can be referenced by the shorter name `Race`. + +## 2. Fix compilation error `Car.__struct__/0 is undefined` + +Add an alias so that the module `NeedForSpeed.RemoteControlCar` can be referenced by the shorter name `Car`. + +## 3. Fix compilation error `undefined function puts/1` + +The function `puts/1` comes from the module `IO`. Import it to be able to use it without referencing the module. + +## 4. Fix compilation error `undefined function default_color/0` + +The functions `default_color/0`, `red/0`, `cyan/0`, and `green/0` all come from the module `IO.ANSI`. You're planning to add support for other car colors, so you want to import the whole module. Unfortunately, the function `color/1` from the module `IO.ANSI` conflicts with one of your local functions. Import the whole `IO.ANSI` module except that one function. + +## Source + +### Created by + +- @angelikatyborska + +### Contributed to by + +- @neenjaw \ No newline at end of file diff --git a/elixir/need-for-speed/lib/need_for_speed.ex b/elixir/need-for-speed/lib/need_for_speed.ex new file mode 100644 index 0000000..2476183 --- /dev/null +++ b/elixir/need-for-speed/lib/need_for_speed.ex @@ -0,0 +1,41 @@ +defmodule NeedForSpeed do + # Add missing aliases and imports here. + alias NeedForSpeed.Race, as: Race + alias NeedForSpeed.RemoteControlCar, as: Car + import IO, only: [puts: 1] + import IO.ANSI, except: [color: 1] + # Do not edit the code below. + + def print_race(%Race{} = race) do + puts(""" + 🏁 #{race.title} 🏁 + Status: #{Race.display_status(race)} + Distance: #{Race.display_distance(race)} + + Contestants: + """) + + race.cars + |> Enum.sort_by(&(-1 * &1.distance_driven_in_meters)) + |> Enum.with_index() + |> Enum.each(fn {car, index} -> print_car(car, index + 1) end) + end + + defp print_car(%Car{} = car, index) do + color = color(car) + + puts(""" + #{index}. #{color}#{car.nickname}#{default_color()} + Distance: #{Car.display_distance(car)} + Battery: #{Car.display_battery(car)} + """) + end + + defp color(%Car{} = car) do + case car.color do + :red -> red() + :blue -> cyan() + :green -> green() + end + end +end diff --git a/elixir/need-for-speed/lib/need_for_speed/race.ex b/elixir/need-for-speed/lib/need_for_speed/race.ex new file mode 100644 index 0000000..170fe96 --- /dev/null +++ b/elixir/need-for-speed/lib/need_for_speed/race.ex @@ -0,0 +1,24 @@ +defmodule NeedForSpeed.Race do + defstruct [ + :title, + :total_distance_in_meters, + cars: [] + ] + + def display_status(%NeedForSpeed.Race{} = race) do + cond do + Enum.any?(race.cars, &(&1.distance_driven_in_meters >= race.total_distance_in_meters)) -> + "Finished" + + Enum.any?(race.cars, &(&1.distance_driven_in_meters > 0)) -> + "In Progress" + + true -> + "Not Started" + end + end + + def display_distance(%NeedForSpeed.Race{total_distance_in_meters: d}) do + "#{d} meters" + end +end diff --git a/elixir/need-for-speed/lib/need_for_speed/remote_control_car.ex b/elixir/need-for-speed/lib/need_for_speed/remote_control_car.ex new file mode 100644 index 0000000..49fed6f --- /dev/null +++ b/elixir/need-for-speed/lib/need_for_speed/remote_control_car.ex @@ -0,0 +1,24 @@ +defmodule NeedForSpeed.RemoteControlCar do + defstruct [ + :nickname, + :color, + battery_percentage: 100, + distance_driven_in_meters: 0 + ] + + def new(color, nickname) when color in [:red, :blue, :green] do + %NeedForSpeed.RemoteControlCar{nickname: nickname, color: color} + end + + def display_distance(%NeedForSpeed.RemoteControlCar{distance_driven_in_meters: d}) do + "#{d} meters" + end + + def display_battery(%NeedForSpeed.RemoteControlCar{battery_percentage: 0}) do + "Battery empty" + end + + def display_battery(%NeedForSpeed.RemoteControlCar{battery_percentage: b}) do + "Battery at #{b}%" + end +end diff --git a/elixir/need-for-speed/mix.exs b/elixir/need-for-speed/mix.exs new file mode 100644 index 0000000..798f006 --- /dev/null +++ b/elixir/need-for-speed/mix.exs @@ -0,0 +1,28 @@ +defmodule RemoteControlCar.MixProject do + use Mix.Project + + def project do + [ + app: :need_for_speed, + 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 diff --git a/elixir/need-for-speed/test/need_for_speed_test.exs b/elixir/need-for-speed/test/need_for_speed_test.exs new file mode 100644 index 0000000..bac497f --- /dev/null +++ b/elixir/need-for-speed/test/need_for_speed_test.exs @@ -0,0 +1,144 @@ +defmodule NeedForSpeedTest do + use ExUnit.Case + + import ExUnit.CaptureIO + + describe "print_race" do + @tag task_id: nil + test "prints a race with no cars" do + race = %NeedForSpeed.Race{ + title: "Need For Speed 2021", + total_distance_in_meters: 350, + cars: [] + } + + io = capture_io(fn -> NeedForSpeed.print_race(race) end) + + assert io == """ + 🏁 Need For Speed 2021 🏁 + Status: Not Started + Distance: 350 meters + + Contestants: + + """ + end + + @tag task_id: nil + test "prints a race with a red car" do + car = NeedForSpeed.RemoteControlCar.new(:red, "The Fox") + + race = %NeedForSpeed.Race{ + title: "Need For Speed 2021", + total_distance_in_meters: 500, + cars: [car] + } + + io = capture_io(fn -> NeedForSpeed.print_race(race) end) + + assert io == """ + 🏁 Need For Speed 2021 🏁 + Status: Not Started + Distance: 500 meters + + Contestants: + + 1. #{IO.ANSI.red()}The Fox#{IO.ANSI.default_color()} + Distance: 0 meters + Battery: Battery at 100% + + """ + end + + @tag task_id: nil + test "prints a race with a blue car" do + car = NeedForSpeed.RemoteControlCar.new(:blue, "The Hurricane") + + race = %NeedForSpeed.Race{ + title: "Need For Speed 2021", + total_distance_in_meters: 500, + cars: [car] + } + + io = capture_io(fn -> NeedForSpeed.print_race(race) end) + + assert io == """ + 🏁 Need For Speed 2021 🏁 + Status: Not Started + Distance: 500 meters + + Contestants: + + 1. #{IO.ANSI.cyan()}The Hurricane#{IO.ANSI.default_color()} + Distance: 0 meters + Battery: Battery at 100% + + """ + end + + @tag task_id: nil + test "prints a race with a green car" do + car = NeedForSpeed.RemoteControlCar.new(:green, "The Grasshopper") + + race = %NeedForSpeed.Race{ + title: "Need For Speed 2021", + total_distance_in_meters: 777, + cars: [car] + } + + io = capture_io(fn -> NeedForSpeed.print_race(race) end) + + assert io == """ + 🏁 Need For Speed 2021 🏁 + Status: Not Started + Distance: 777 meters + + Contestants: + + 1. #{IO.ANSI.green()}The Grasshopper#{IO.ANSI.default_color()} + Distance: 0 meters + Battery: Battery at 100% + + """ + end + + @tag task_id: nil + test "prints a race in progress with many cars" do + red_car = NeedForSpeed.RemoteControlCar.new(:red, "The Fox") + blue_car = NeedForSpeed.RemoteControlCar.new(:blue, "The Hurricane") + green_car = NeedForSpeed.RemoteControlCar.new(:green, "The Grasshopper") + red_car = %{red_car | distance_driven_in_meters: 305, battery_percentage: 70} + blue_car = %{blue_car | distance_driven_in_meters: 500, battery_percentage: 62} + green_car = %{green_car | distance_driven_in_meters: 235, battery_percentage: 60} + + race = %NeedForSpeed.Race{ + title: "Need For Speed 2021", + total_distance_in_meters: 1000, + cars: [red_car, blue_car, green_car] + } + + io = capture_io(fn -> NeedForSpeed.print_race(race) end) + + assert io == """ + 🏁 Need For Speed 2021 🏁 + Status: In Progress + Distance: 1000 meters + + Contestants: + + 1. #{IO.ANSI.cyan()}The Hurricane#{IO.ANSI.default_color()} + Distance: 500 meters + Battery: Battery at 62% + + 2. #{IO.ANSI.red()}The Fox#{IO.ANSI.default_color()} + Distance: 305 meters + Battery: Battery at 70% + + 3. #{IO.ANSI.green()}The Grasshopper#{IO.ANSI.default_color()} + Distance: 235 meters + Battery: Battery at 60% + + """ + end + end +end diff --git a/elixir/need-for-speed/test/test_helper.exs b/elixir/need-for-speed/test/test_helper.exs new file mode 100644 index 0000000..35fc5bf --- /dev/null +++ b/elixir/need-for-speed/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true) diff --git a/elixir/newsletter/.exercism/config.json b/elixir/newsletter/.exercism/config.json new file mode 100644 index 0000000..6fb0b15 --- /dev/null +++ b/elixir/newsletter/.exercism/config.json @@ -0,0 +1,21 @@ +{ + "authors": [ + "angelikatyborska" + ], + "contributors": [ + "neenjaw" + ], + "files": { + "solution": [ + "lib/newsletter.ex" + ], + "test": [ + "test/newsletter_test.exs" + ], + "exemplar": [ + ".meta/exemplar.ex" + ] + }, + "language_versions": ">=1.10", + "blurb": "Learn about working with files by sending out a newsletter." +} diff --git a/elixir/newsletter/.exercism/metadata.json b/elixir/newsletter/.exercism/metadata.json new file mode 100644 index 0000000..abe291b --- /dev/null +++ b/elixir/newsletter/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"newsletter","id":"e5210ea9bb054411a80a04ce1e69780d","url":"https://exercism.org/tracks/elixir/exercises/newsletter","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/newsletter/.formatter.exs b/elixir/newsletter/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/newsletter/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/newsletter/.gitignore b/elixir/newsletter/.gitignore new file mode 100644 index 0000000..4abee35 --- /dev/null +++ b/elixir/newsletter/.gitignore @@ -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"). +match_binary-*.tar + diff --git a/elixir/newsletter/HELP.md b/elixir/newsletter/HELP.md new file mode 100644 index 0000000..6e923e3 --- /dev/null +++ b/elixir/newsletter/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/newsletter.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/newsletter/HINTS.md b/elixir/newsletter/HINTS.md new file mode 100644 index 0000000..c50bf86 --- /dev/null +++ b/elixir/newsletter/HINTS.md @@ -0,0 +1,40 @@ +# Hints + +## 1. General + +- Read about files in the official [Getting Started guide][getting-started-file]. +- Read about files on [joyofelixir.com][joy-of-elixir-file]. +- Take a look at the [documentation of the `File` module][file]. + +## 1. Read email addresses from a file + +- There is a [built-in function][file-read] for reading the contents of a file all at once. + +## 2. Open a log file for writing + +- There is a [built-in function][file-open] for opening a file. +- The second argument of that function is a list of modes which allows specifying that the file should be opened for writing. + +## 3. Log a sent email + +- Functions for reading and writing to a file opened with [`File.open!/1`][file-open] can be found in the [`IO`][io] module. +- There is a [built-in function][io-puts] for writing a string to a file, followed by a newline. + +## 4. Close the log file + +- There is a [built-in function][file-close] for closing a file. + +## 5. Send the newsletter + +- All the necessary operations on files were already implemented in the previous steps. +- Before writing to a file, the file must be opened. +- After all write operations to a file finished, the file should be closed. + +[getting-started-file]: https://elixir-lang.org/getting-started/io-and-the-file-system.html#the-file-module +[joy-of-elixir-file]: https://joyofelixir.com/11-files/ +[file]: https://hexdocs.pm/elixir/File.html +[file-read]: https://hexdocs.pm/elixir/File.html#read!/1 +[file-open]: https://hexdocs.pm/elixir/File.html#open!/1 +[file-close]: https://hexdocs.pm/elixir/File.html#close/1 +[io]: https://hexdocs.pm/elixir/IO.html +[io-puts]: https://hexdocs.pm/elixir/IO.html#puts/2 \ No newline at end of file diff --git a/elixir/newsletter/README.md b/elixir/newsletter/README.md new file mode 100644 index 0000000..88c24e4 --- /dev/null +++ b/elixir/newsletter/README.md @@ -0,0 +1,92 @@ +# Newsletter + +Welcome to Newsletter 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 + +## File + +Functions for working with files are provided by the `File` module. + +To read a whole file, use `File.read/1`. To write to a file, use `File.write/2`. + +Every time a file is written to with `File.write/2`, a file descriptor is opened and a new Elixir [process][exercism-processes] is spawned. For this reason, writing to a file in a loop using `File.write/2` should be avoided. + +Instead, a file can be opened using `File.open/2`. The second argument to `File.open/2` is a list of modes, which allows you to specify if you want to open the file for reading or for writing. + +`File.open/2` returns a PID of a process that handles the file. To read and write to the file, use functions from the `IO` module and pass this PID as the IO device. + +When you're finished working with the file, close it with `File.close/1`. + +All the mentioned functions from the `File` module also have a `!` variant that raises an error instead of returning an error tuple (e.g. `File.read!/1`). Use that variant if you don't intend to handle errors such as missing files or lack of permissions. + +[exercism-processes]: https://exercism.org/tracks/elixir/concepts/processes + +## Instructions + +You're a big model train enthusiast and have decided to share your passion with the world by starting a newsletter. You'll start by sending the first issue of your newsletter to your friends and acquaintances that share your hobby. You have a text file with a list of their email addresses. + +## 1. Read email addresses from a file + +Implement the `Newsletter.read_emails/1` function. It should take a file path. The file is a text file that contains email addresses separated by newlines. The function should return a list of the email addresses from the file. + +```elixir +Newsletter.read_emails("/home/my_user/documents/model_train_friends_emails.txt") +# => ["rick@example.com", "choochoo42@example.com", "anna@example.com"] +``` + +## 2. Open a log file for writing + +Sending an email is a task that might fail for many unpredictable reasons, like a typo in the email address or temporary network issues. To ensure that you can retry sending the emails to all your friends without sending duplicates, you need to log the email addresses that already received the email. For this, you'll need a log file. + +Implement the `Newsletter.open_log/1` function. It should take a file path, open the file for writing, and return the PID of the process that handles the file. + +```elixir +Newsletter.open_log("/home/my_user/documents/newsletter_issue1_log.txt") +# => #PID<0.145.0> +``` + +## 3. Log a sent email + +Implement the `Newsletter.log_sent_email/2` function. It should take a PID of the process that handles the file and a string with the email address. It should write the email address to the file, followed by a newline. + +```elixir +Newsletter.log_sent_email(pid, "joe@example.com") +# => :ok +``` + +## 4. Close the log file + +Implement the `Newsletter.close_log/1` function. It should take a PID of the process that handles the file and close the file. + +```elixir +Newsletter.close_log(pid) +# => :ok +``` + +## 5. Send the newsletter + +Now that you have all of the building blocks of the email sending procedure, you need to combine them together in a single function. + +Implement the `Newsletter.send_newsletter/3` function. It should take a path of the file with email addresses, a path of a log file, and an anonymous function that sends an email to a given email address. It should read all the email addresses from the given file and attempt to send an email to every one of them. If the anonymous function that sends the email returns `:ok`, write the email address to the log file, followed by a new line. Make sure to do it as soon as the email is sent. Afterwards, close the log file. + +```elixir +Newsletter.send_newsletter( + "model_train_friends_emails.txt", + "newsletter_issue1_log.txt", + fn email -> :ok end +) +# => :ok +``` + +## Source + +### Created by + +- @angelikatyborska + +### Contributed to by + +- @neenjaw \ No newline at end of file diff --git a/elixir/newsletter/assets/emails.txt b/elixir/newsletter/assets/emails.txt new file mode 100644 index 0000000..1f12bcb --- /dev/null +++ b/elixir/newsletter/assets/emails.txt @@ -0,0 +1,4 @@ +alice@example.com +bob@example.com +charlie@example.com +dave@example.com diff --git a/elixir/newsletter/assets/empty.txt b/elixir/newsletter/assets/empty.txt new file mode 100644 index 0000000..e69de29 diff --git a/elixir/newsletter/lib/newsletter.ex b/elixir/newsletter/lib/newsletter.ex new file mode 100644 index 0000000..02823ae --- /dev/null +++ b/elixir/newsletter/lib/newsletter.ex @@ -0,0 +1,28 @@ +defmodule Newsletter do + def read_emails(path) do + File.read!(path) |> String.split("\n", trim: true) + end + + def open_log(path) do + File.open!(path, [:write]) + end + + def log_sent_email(pid, email) do + IO.puts(pid, "#{email}") + end + + def close_log(pid) do + File.close(pid) + end + + def send_newsletter(emails_path, log_path, send_fun) do + log = open_log(log_path) + read_emails(emails_path) + |> Enum.map(fn email -> + with :ok <- send_fun.(email) do + log_sent_email(log, email) + end + end) + close_log(log) + end +end diff --git a/elixir/newsletter/mix.exs b/elixir/newsletter/mix.exs new file mode 100644 index 0000000..93fb4fb --- /dev/null +++ b/elixir/newsletter/mix.exs @@ -0,0 +1,28 @@ +defmodule Newsletter.MixProject do + use Mix.Project + + def project do + [ + app: :newsletter, + 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 diff --git a/elixir/newsletter/test/newsletter_test.exs b/elixir/newsletter/test/newsletter_test.exs new file mode 100644 index 0000000..d1148af --- /dev/null +++ b/elixir/newsletter/test/newsletter_test.exs @@ -0,0 +1,206 @@ +defmodule NewsletterTest do + # run test synchronously to be able to use the same file path for all tests without write conflicts + use ExUnit.Case, async: false + + @temp_file_path Path.join(["assets", "temp.txt"]) + + setup do + File.write!(@temp_file_path, "") + on_exit(fn -> File.rm!(@temp_file_path) end) + end + + describe "read_emails" do + @tag task_id: 1 + test "returns a list of all lines in a file" do + emails_file_path = Path.join(["assets", "emails.txt"]) + + assert Newsletter.read_emails(emails_file_path) == [ + "alice@example.com", + "bob@example.com", + "charlie@example.com", + "dave@example.com" + ] + end + + @tag task_id: 1 + test "returns an empty list if the file is empty" do + empty_file_path = Path.join(["assets", "empty.txt"]) + assert Newsletter.read_emails(empty_file_path) == [] + end + end + + describe "open_log" do + @tag task_id: 2 + test "returns a pid" do + file = Newsletter.open_log(@temp_file_path) + assert is_pid(file) + File.close(file) + end + + @tag task_id: 2 + test "opens the file for writing" do + file = Newsletter.open_log(@temp_file_path) + assert IO.write(file, "hello") == :ok + assert File.read!(@temp_file_path) == "hello" + File.close(file) + end + end + + describe "log_sent_email" do + @tag task_id: 3 + test "returns ok" do + file = File.open!(@temp_file_path, [:write]) + assert Newsletter.log_sent_email(file, "janice@example.com") == :ok + File.close(file) + end + + @tag task_id: 3 + test "writes the email address to the given file" do + file = File.open!(@temp_file_path, [:write]) + Newsletter.log_sent_email(file, "joe@example.com") + assert File.read!(@temp_file_path) == "joe@example.com\n" + File.close(file) + end + + @tag task_id: 3 + test "writes many email addresses to the given file" do + file = File.open!(@temp_file_path, [:write]) + Newsletter.log_sent_email(file, "joe@example.com") + Newsletter.log_sent_email(file, "kathrine@example.com") + Newsletter.log_sent_email(file, "lina@example.com") + + assert File.read!(@temp_file_path) == + "joe@example.com\nkathrine@example.com\nlina@example.com\n" + + File.close(file) + end + end + + describe "close_log" do + @tag task_id: 4 + test "returns ok" do + file = File.open!(@temp_file_path, [:write]) + assert Newsletter.close_log(file) == :ok + end + + @tag task_id: 4 + test "closes the file" do + file = File.open!(@temp_file_path, [:read]) + assert Newsletter.close_log(file) == :ok + assert IO.read(file, :all) == {:error, :terminated} + end + end + + describe "send_newsletter" do + @tag task_id: 5 + test "returns ok" do + send_fun = fn _ -> :ok end + + assert Newsletter.send_newsletter( + Path.join(["assets", "emails.txt"]), + @temp_file_path, + send_fun + ) == :ok + end + + @tag task_id: 5 + test "calls send function for every email from the emails file" do + send_fun = fn email -> send(self(), {:send, email}) && :ok end + + Newsletter.send_newsletter(Path.join(["assets", "emails.txt"]), @temp_file_path, send_fun) + + assert_received {:send, "alice@example.com"} + assert_received {:send, "bob@example.com"} + assert_received {:send, "charlie@example.com"} + assert_received {:send, "dave@example.com"} + end + + @tag task_id: 5 + test "logs emails that were sent" do + send_fun = fn _ -> :ok end + + Newsletter.send_newsletter(Path.join(["assets", "emails.txt"]), @temp_file_path, send_fun) + + assert File.read!(@temp_file_path) == + """ + alice@example.com + bob@example.com + charlie@example.com + dave@example.com + """ + end + + @tag task_id: 5 + test "does not log emails that could not be sent" do + send_fun = fn + "bob@example.com" -> :error + "charlie@example.com" -> :error + _ -> :ok + end + + Newsletter.send_newsletter(Path.join(["assets", "emails.txt"]), @temp_file_path, send_fun) + + assert File.read!(@temp_file_path) == """ + alice@example.com + dave@example.com + """ + end + + @tag task_id: 5 + test "sending the same newsletter twice resets the log" do + send_fun = fn _ -> :ok end + Newsletter.send_newsletter(Path.join(["assets", "emails.txt"]), @temp_file_path, send_fun) + Newsletter.send_newsletter(Path.join(["assets", "emails.txt"]), @temp_file_path, send_fun) + + assert File.read!(@temp_file_path) == + """ + alice@example.com + bob@example.com + charlie@example.com + dave@example.com + """ + end + + @tag task_id: 5 + test "logs the email immediately after it was sent" do + send_fun = fn email -> + case email do + "alice@example.com" -> + :ok + + "bob@example.com" -> + assert File.read!(@temp_file_path) == """ + alice@example.com + """ + + :ok + + "charlie@example.com" -> + assert File.read!(@temp_file_path) == """ + alice@example.com + bob@example.com + """ + + :error + + "dave@example.com" -> + assert File.read!(@temp_file_path) == """ + alice@example.com + bob@example.com + """ + + :ok + end + end + + Newsletter.send_newsletter(Path.join(["assets", "emails.txt"]), @temp_file_path, send_fun) + + assert File.read!(@temp_file_path) == + """ + alice@example.com + bob@example.com + dave@example.com + """ + end + end +end diff --git a/elixir/newsletter/test/test_helper.exs b/elixir/newsletter/test/test_helper.exs new file mode 100644 index 0000000..e8677a3 --- /dev/null +++ b/elixir/newsletter/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true, seed: 0) diff --git a/elixir/remote-control-car/.exercism/config.json b/elixir/remote-control-car/.exercism/config.json new file mode 100644 index 0000000..1c837b9 --- /dev/null +++ b/elixir/remote-control-car/.exercism/config.json @@ -0,0 +1,25 @@ +{ + "authors": [ + "neenjaw" + ], + "contributors": [ + "angelikatyborska" + ], + "files": { + "solution": [ + "lib/remote_control_car.ex" + ], + "test": [ + "test/remote_control_car_test.exs" + ], + "exemplar": [ + ".meta/exemplar.ex" + ] + }, + "language_versions": ">=1.10", + "forked_from": [ + "csharp/elons-toys" + ], + "icon": "elons-toys", + "blurb": "Learn about structs by playing around with a remote controlled car." +} diff --git a/elixir/remote-control-car/.exercism/metadata.json b/elixir/remote-control-car/.exercism/metadata.json new file mode 100644 index 0000000..925033e --- /dev/null +++ b/elixir/remote-control-car/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"remote-control-car","id":"994a66b4115e4b5eb955a1e2d289cf91","url":"https://exercism.org/tracks/elixir/exercises/remote-control-car","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/remote-control-car/.formatter.exs b/elixir/remote-control-car/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/remote-control-car/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/remote-control-car/.gitignore b/elixir/remote-control-car/.gitignore new file mode 100644 index 0000000..b97fe0c --- /dev/null +++ b/elixir/remote-control-car/.gitignore @@ -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"). +structs-*.tar + diff --git a/elixir/remote-control-car/HELP.md b/elixir/remote-control-car/HELP.md new file mode 100644 index 0000000..154e1d2 --- /dev/null +++ b/elixir/remote-control-car/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/remote_control_car.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/remote-control-car/HINTS.md b/elixir/remote-control-car/HINTS.md new file mode 100644 index 0000000..ae520cc --- /dev/null +++ b/elixir/remote-control-car/HINTS.md @@ -0,0 +1,44 @@ +# Hints + +## General + +- Read about [structs][getting-started-structs] in the Getting Started guide. +- Read about [`defstruct`][docs-defstruct] in the documentation. +- Watch [Elixir Casts - #106: Intro to Structs][elixir-casts]. + +## 1. Create a brand-new remote controlled car + +- The module attribute `@enforce_keys` can be used to specify required values. It needs to be defined before calling `defstruct`. +- The `nickname` field should not have a default value specified. +- The `new/0` function should initialize the `nickname` with the value `"none"`. + +## 2. Create a brand-new remote controlled car with a nickname + +- Use [`multiple-function-clauses`][multiple-fn-clauses] to reuse the function name but accept different arguments. +- Consider a [`default-argument`][default-arg] for the function. + +## 3. Display the distance + +- For functions which accept only a specific type of struct, make sure you perform a pattern match to check the argument. +- Use the _static access operator_ to obtain field values. + +## 4. Display the battery percentage + +- For functions which accept only a specific type of struct, make sure you perform a pattern match to check the argument. +- Use the _static access operator_ to obtain field values. + +## 5. Driving changes the battery and distance driven + +- For functions which accept only a specific type of struct, make sure you perform a pattern match to check the argument. +- Use the _static access operator_ to obtain field values. +- Review the introduction for updating structs. + +## 6. Account for driving with a dead battery + +- If the battery is dead, it should return the struct unchanged. + +[getting-started-structs]: https://elixir-lang.org/getting-started/structs.html +[docs-defstruct]: https://hexdocs.pm/elixir/Kernel.html#defstruct/1 +[elixir-casts]: https://elixircasts.io/intro-to-structs +[multiple-fn-clauses]: https://elixir-lang.org/getting-started/modules-and-functions.html#named-functions +[default-arg]: https://elixir-lang.org/getting-started/modules-and-functions.html#default-arguments \ No newline at end of file diff --git a/elixir/remote-control-car/README.md b/elixir/remote-control-car/README.md new file mode 100644 index 0000000..aa255e9 --- /dev/null +++ b/elixir/remote-control-car/README.md @@ -0,0 +1,171 @@ +# Remote Control Car + +Welcome to Remote Control Car 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 + +## Structs + +Structs are an extension built on top of [maps][exercism-maps] which provide compile-time checks and default values. A struct is named after the module it is defined in. To define a struct use the `defstruct` construct. The construct usually immediately follows after the module definition. `defstruct` accepts either a list of atoms (for `nil` default values) or a keyword list (for specified default values). The fields without defaults must precede the fields with default values. + +```elixir +defmodule Plane do + defstruct [:engine, wings: 2] +end + +plane = %Plane{} +# => %Plane{engine: nil, wings: 2} +``` + +### Accessing fields and updating + +Since structs are built on maps, we can use most map functions to get and manipulate values. The _Access Behaviour_ is **not** implemented for structs. It is recommended to use the _static access operator_ `.` to access struct fields instead. + +- get/fetch field values: + + ```elixir + plane = %Plane{} + plane.engine + # => nil + Map.fetch(plane, :wings) + # => 2 + ``` + +- update field values + + ```elixir + plane = %Plane{} + %{plane | wings: 4} + # => %Plane{engine: nil, wings: 4} + ``` + +### Enforcing field value initialization + +We can use the `@enforce_keys` module attribute with a list of the field keys to ensure that the values are initialized when the struct is created. If a key is not listed, its value will be `nil` as seen in the above example. If an enforced key is not initialized, an error is raised. + +```elixir +defmodule User do + @enforce_keys [:username] + defstruct [:username] +end + +%User{} +# => (ArgumentError) the following keys must also be given when building struct User: [:username] +``` + +[exercism-maps]: https://exercism.org/tracks/elixir/concepts/maps + +## Instructions + +In this exercise you'll be playing around with a remote controlled car, which you've finally saved enough money for to buy. + +Cars start with full (100%) batteries. Each time you drive the car using the remote control, it covers 20 meters and drains one percent of the battery. The car's nickname is not known until it is created. + +The remote controlled car has a fancy LED display that shows two bits of information: + +- The total distance it has driven, displayed as: `" meters"`. +- The remaining battery charge, displayed as: `"Battery at %"`. + +If the battery is at 0%, you can't drive the car anymore and the battery display will show `"Battery empty"`. + +## 1. Create a brand-new remote controlled car + +Implement the `RemoteControlCar.new/0` function to return a brand-new remote controlled car struct: + +```elixir +RemoteControlCar.new() +# => %RemoteControlCar{ +# battery_percentage: 100, +# distance_driven_in_meters: 0, +# nickname: "none" +# } +``` + +The nickname is required by the struct, make sure that a value is initialized in the `new` function, but not in the struct. + +## 2. Create a brand-new remote controlled car with a nickname + +Implement the `RemoteControlCar.new/1` function to return a brand-new remote controlled car struct with a provided nickname: + +```elixir +RemoteControlCar.new("Blue") +# => %RemoteControlCar{ +# battery_percentage: 100, +# distance_driven_in_meters: 0, +# nickname: "Blue" +# } +``` + +## 3. Display the distance + +Implement the `RemoteControlCar.display_distance/1` function to return the distance as displayed on the LED display: + +```elixir +car = RemoteControlCar.new() +RemoteControlCar.display_distance(car) +# => "0 meters" +``` + +Make sure the function only accepts a `RemoteControlCar` struct as the argument. + +## 4. Display the battery percentage + +Implement the `RemoteControlCar.display_battery/1` function to return the battery percentage as displayed on the LED display: + +```elixir +car = RemoteControlCar.new() +RemoteControlCar.display_battery(car) +# => "Battery at 100%" +``` + +Make sure the function only accepts a `RemoteControlCar` struct as the argument. If the battery is at 0%, the battery display will show "Battery empty". + +## 5. Driving changes the battery and distance driven + +Implement the `RemoteControlCar.drive/1` function that: + +- updates the number of meters driven by 20 +- drains 1% of the battery + +```elixir +RemoteControlCar.new("Red") +|> RemoteControlCar.drive() +# => %RemoteControlCar{ +# battery_percentage: 99, +# distance_driven_in_meters: 20, +# nickname: "Red" +# } + +``` + +Make sure the function only accepts a `RemoteControlCar` struct as the argument. + +## 6. Account for driving with a dead battery + +Update the `RemoteControlCar.drive/1` function to not increase the distance driven nor decrease the battery percentage when the battery is drained (at 0%): + +```elixir +%RemoteControlCar{ + battery_percentage: 0, + distance_driven_in_meters: 1980, + nickname: "Red" +} +|> RemoteControlCar.drive() +# => %RemoteControlCar{ +# battery_percentage: 0, +# distance_driven_in_meters: 1980, +# nickname: "Red" +# } +``` + +## Source + +### Created by + +- @neenjaw + +### Contributed to by + +- @angelikatyborska \ No newline at end of file diff --git a/elixir/remote-control-car/lib/remote_control_car.ex b/elixir/remote-control-car/lib/remote_control_car.ex new file mode 100644 index 0000000..7c6e4cb --- /dev/null +++ b/elixir/remote-control-car/lib/remote_control_car.ex @@ -0,0 +1,25 @@ +defmodule RemoteControlCar do + @enforce_keys [:nickname] + defstruct [:nickname, battery_percentage: 100, distance_driven_in_meters: 0] + + def new(nickname \\ "none") do + %RemoteControlCar{nickname: nickname} + end + + def display_distance(%RemoteControlCar{} = remote_car) do + "#{remote_car.distance_driven_in_meters} meters" + end + + def display_battery(%RemoteControlCar{} = car) do + if car.battery_percentage > 0 do + "Battery at #{car.battery_percentage}%" + else + "Battery empty" + end + end + + def drive(%RemoteControlCar{} = remote_car) when remote_car.battery_percentage > 0 do + %{remote_car | battery_percentage: remote_car.battery_percentage - 1, distance_driven_in_meters: remote_car.distance_driven_in_meters + 20} + end + def drive(%RemoteControlCar{} = car), do: car +end diff --git a/elixir/remote-control-car/mix.exs b/elixir/remote-control-car/mix.exs new file mode 100644 index 0000000..6d49c1d --- /dev/null +++ b/elixir/remote-control-car/mix.exs @@ -0,0 +1,28 @@ +defmodule RemoteControlCar.MixProject do + use Mix.Project + + def project do + [ + app: :remote_control_car, + 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 diff --git a/elixir/remote-control-car/test/remote_control_car_test.exs b/elixir/remote-control-car/test/remote_control_car_test.exs new file mode 100644 index 0000000..de20d0f --- /dev/null +++ b/elixir/remote-control-car/test/remote_control_car_test.exs @@ -0,0 +1,169 @@ +defmodule FakeRemoteControlCar do + defstruct battery_percentage: 100, + distance_driven_in_meters: 0, + nickname: nil +end + +defmodule RemoteControlCarTest do + use ExUnit.Case + + @tag task_id: 1 + test "required key 'nickname' should not have a default value" do + assert_raise ArgumentError, fn -> + quote do + %RemoteControlCar{} + end + |> Code.eval_quoted() + end + end + + @tag task_id: 1 + test "new" do + car = RemoteControlCar.new() + + assert car.__struct__ == RemoteControlCar + assert car.battery_percentage == 100 + assert car.distance_driven_in_meters == 0 + assert car.nickname == "none" + end + + @tag task_id: 2 + test "new with nickname" do + nickname = "Red" + car = RemoteControlCar.new(nickname) + + assert car.__struct__ == RemoteControlCar + assert car.battery_percentage == 100 + assert car.distance_driven_in_meters == 0 + assert car.nickname == nickname + end + + @tag task_id: 3 + test "display distance raises error when not given struct" do + fake_car = %{ + battery_percentage: 100, + distance_driven_in_meters: 0, + nickname: "Fake" + } + + assert_raise(FunctionClauseError, fn -> + RemoteControlCar.display_distance(fake_car) + end) + end + + @tag task_id: 3 + test "display distance raises error when given unexpected struct" do + fake_car = %FakeRemoteControlCar{ + battery_percentage: 100, + distance_driven_in_meters: 0, + nickname: "Fake" + } + + assert_raise(FunctionClauseError, fn -> + RemoteControlCar.display_distance(fake_car) + end) + end + + @tag task_id: 3 + test "display distance of new" do + car = RemoteControlCar.new() + + assert RemoteControlCar.display_distance(car) == "0 meters" + end + + @tag task_id: 3 + test "display distance of driven" do + car = RemoteControlCar.new() + car = %{car | distance_driven_in_meters: 20} + + assert RemoteControlCar.display_distance(car) == "20 meters" + end + + @tag task_id: 4 + test "display battery raises error when not given struct" do + fake_car = %{ + battery_percentage: 100, + distance_driven_in_meters: 0, + nickname: "Fake" + } + + assert_raise(FunctionClauseError, fn -> + RemoteControlCar.display_battery(fake_car) + end) + end + + @tag task_id: 4 + test "display battery raises error when given unexpected struct" do + fake_car = %FakeRemoteControlCar{ + battery_percentage: 100, + distance_driven_in_meters: 0, + nickname: "Fake" + } + + assert_raise(FunctionClauseError, fn -> + RemoteControlCar.display_battery(fake_car) + end) + end + + @tag task_id: 4 + test "display battery of new" do + car = RemoteControlCar.new() + + assert RemoteControlCar.display_battery(car) == "Battery at 100%" + end + + @tag task_id: 4 + test "display battery of dead battery" do + car = RemoteControlCar.new() + car = %{car | battery_percentage: 0} + + assert RemoteControlCar.display_battery(car) == "Battery empty" + end + + @tag task_id: 5 + test "drive raises error when not given struct" do + fake_car = %{ + battery_percentage: 100, + distance_driven_in_meters: 0, + nickname: "Fake" + } + + assert_raise(FunctionClauseError, fn -> + RemoteControlCar.drive(fake_car) + end) + end + + @tag task_id: 5 + test "drive raises error when given unexpected struct" do + fake_car = %FakeRemoteControlCar{ + battery_percentage: 100, + distance_driven_in_meters: 0, + nickname: "Fake" + } + + assert_raise(FunctionClauseError, fn -> + RemoteControlCar.drive(fake_car) + end) + end + + @tag task_id: 5 + test "drive with battery" do + car = RemoteControlCar.new() |> RemoteControlCar.drive() + + assert car.__struct__ == RemoteControlCar + assert car.battery_percentage == 99 + assert car.distance_driven_in_meters == 20 + end + + @tag task_id: 6 + test "drive with dead battery" do + car = + RemoteControlCar.new() + |> Map.put(:battery_percentage, 0) + |> RemoteControlCar.drive() + + assert car.__struct__ == RemoteControlCar + assert car.battery_percentage == 0 + assert car.distance_driven_in_meters == 0 + end +end diff --git a/elixir/remote-control-car/test/test_helper.exs b/elixir/remote-control-car/test/test_helper.exs new file mode 100644 index 0000000..e8677a3 --- /dev/null +++ b/elixir/remote-control-car/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true, seed: 0) diff --git a/elixir/resistor-color/.exercism/config.json b/elixir/resistor-color/.exercism/config.json new file mode 100644 index 0000000..5185b3d --- /dev/null +++ b/elixir/resistor-color/.exercism/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "Bscruz19" + ], + "contributors": [ + "angelikatyborska" + ], + "files": { + "solution": [ + "lib/resistor_color.ex" + ], + "test": [ + "test/resistor_color_test.exs" + ], + "example": [ + ".meta/example.ex" + ] + }, + "blurb": "Convert a resistor band's color to its numeric representation.", + "source": "Maud de Vries, Erik Schierboom", + "source_url": "https://github.com/exercism/problem-specifications/issues/1458" +} diff --git a/elixir/resistor-color/.exercism/metadata.json b/elixir/resistor-color/.exercism/metadata.json new file mode 100644 index 0000000..bc8f061 --- /dev/null +++ b/elixir/resistor-color/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"resistor-color","id":"6cbe5be0c48246928be738b759e13520","url":"https://exercism.org/tracks/elixir/exercises/resistor-color","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/resistor-color/.formatter.exs b/elixir/resistor-color/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/resistor-color/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/resistor-color/.gitignore b/elixir/resistor-color/.gitignore new file mode 100644 index 0000000..f87bc03 --- /dev/null +++ b/elixir/resistor-color/.gitignore @@ -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"). +resistor_color-*.tar + diff --git a/elixir/resistor-color/HELP.md b/elixir/resistor-color/HELP.md new file mode 100644 index 0000000..c022ccf --- /dev/null +++ b/elixir/resistor-color/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/resistor_color.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/resistor-color/README.md b/elixir/resistor-color/README.md new file mode 100644 index 0000000..a7e950c --- /dev/null +++ b/elixir/resistor-color/README.md @@ -0,0 +1,57 @@ +# Resistor Color + +Welcome to Resistor Color on Exercism's Elixir Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +If you want to build something using a Raspberry Pi, you'll probably use _resistors_. +For this exercise, you need to know two things about them: + +- Each resistor has a resistance value. +- Resistors are small - so small in fact that if you printed the resistance value on them, it would be hard to read. + +To get around this problem, manufacturers print color-coded bands onto the resistors to denote their resistance values. +Each band has a position and a numeric value. + +The first 2 bands of a resistor have a simple encoding scheme: each color maps to a single number. + +In this exercise you are going to create a helpful program so that you don't have to remember the values of the bands. + +These colors are encoded as follows: + +- Black: 0 +- Brown: 1 +- Red: 2 +- Orange: 3 +- Yellow: 4 +- Green: 5 +- Blue: 6 +- Violet: 7 +- Grey: 8 +- White: 9 + +The goal of this exercise is to create a way: + +- to look up the numerical value associated with a particular color band +- to list the different band colors + +Mnemonics map the colors to the numbers, that, when stored as an array, happen to map to their index in the array: Better Be Right Or Your Great Big Values Go Wrong. + +More information on the color encoding of resistors can be found in the [Electronic color code Wikipedia article](https://en.wikipedia.org/wiki/Electronic_color_code) + +For this exercise, returning the list of colors is not required. + +## Source + +### Created by + +- @Bscruz19 + +### Contributed to by + +- @angelikatyborska + +### Based on + +Maud de Vries, Erik Schierboom - https://github.com/exercism/problem-specifications/issues/1458 \ No newline at end of file diff --git a/elixir/resistor-color/lib/resistor_color.ex b/elixir/resistor-color/lib/resistor_color.ex new file mode 100644 index 0000000..971b498 --- /dev/null +++ b/elixir/resistor-color/lib/resistor_color.ex @@ -0,0 +1,21 @@ +defmodule ResistorColor do + @resistors %{ + black: 0, + brown: 1, + red: 2, + orange: 3, + yellow: 4, + green: 5, + blue: 6, + violet: 7, + grey: 8, + white: 9 + } + @doc """ + Return the value of a color band + """ + @spec code(atom) :: integer() + def code(color) when is_map_key(@resistors, color) do + @resistors[color] + end +end diff --git a/elixir/resistor-color/mix.exs b/elixir/resistor-color/mix.exs new file mode 100644 index 0000000..5c175d1 --- /dev/null +++ b/elixir/resistor-color/mix.exs @@ -0,0 +1,28 @@ +defmodule ResistorColor.MixProject do + use Mix.Project + + def project do + [ + app: :resistor_color, + 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 diff --git a/elixir/resistor-color/test/resistor_color_test.exs b/elixir/resistor-color/test/resistor_color_test.exs new file mode 100644 index 0000000..fba0251 --- /dev/null +++ b/elixir/resistor-color/test/resistor_color_test.exs @@ -0,0 +1,44 @@ +defmodule ResistorColorTest do + use ExUnit.Case + + # @tag :pending + test "returns black color code" do + assert ResistorColor.code(:black) == 0 + end + + test "returns brown color code" do + assert ResistorColor.code(:brown) == 1 + end + + test "returns red color code" do + assert ResistorColor.code(:red) == 2 + end + + test "returns orange color code" do + assert ResistorColor.code(:orange) == 3 + end + + test "returns yellow color code" do + assert ResistorColor.code(:yellow) == 4 + end + + test "returns green color code" do + assert ResistorColor.code(:green) == 5 + end + + test "returns blue color code" do + assert ResistorColor.code(:blue) == 6 + end + + test "returns violet color code" do + assert ResistorColor.code(:violet) == 7 + end + + test "returns grey color code" do + assert ResistorColor.code(:grey) == 8 + end + + test "returns white color code" do + assert ResistorColor.code(:white) == 9 + end +end diff --git a/elixir/resistor-color/test/test_helper.exs b/elixir/resistor-color/test/test_helper.exs new file mode 100644 index 0000000..35fc5bf --- /dev/null +++ b/elixir/resistor-color/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true) diff --git a/elixir/rpn-calculator/.exercism/config.json b/elixir/rpn-calculator/.exercism/config.json new file mode 100644 index 0000000..3767236 --- /dev/null +++ b/elixir/rpn-calculator/.exercism/config.json @@ -0,0 +1,23 @@ +{ + "authors": [ + "neenjaw" + ], + "contributors": [ + "angelikatyborska", + "cjmaxik" + ], + "files": { + "solution": [ + "lib/rpn_calculator.ex" + ], + "test": [ + "test/rpn_calculator_test.exs" + ], + "exemplar": [ + ".meta/exemplar.ex" + ] + }, + "language_versions": ">=1.10", + "icon": "instruments-of-texas", + "blurb": "Learn about errors and rescuing them by working on an experimental Reverse Polish Notation calculator." +} diff --git a/elixir/rpn-calculator/.exercism/metadata.json b/elixir/rpn-calculator/.exercism/metadata.json new file mode 100644 index 0000000..648d3e8 --- /dev/null +++ b/elixir/rpn-calculator/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"rpn-calculator","id":"cdf1606c25f84158a87ad49c784d0ef2","url":"https://exercism.org/tracks/elixir/exercises/rpn-calculator","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/rpn-calculator/.formatter.exs b/elixir/rpn-calculator/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/rpn-calculator/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/rpn-calculator/.gitignore b/elixir/rpn-calculator/.gitignore new file mode 100644 index 0000000..d343c0d --- /dev/null +++ b/elixir/rpn-calculator/.gitignore @@ -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"). +errors-*.tar + diff --git a/elixir/rpn-calculator/HELP.md b/elixir/rpn-calculator/HELP.md new file mode 100644 index 0000000..4203b5a --- /dev/null +++ b/elixir/rpn-calculator/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/rpn_calculator.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/rpn-calculator/HINTS.md b/elixir/rpn-calculator/HINTS.md new file mode 100644 index 0000000..08236c5 --- /dev/null +++ b/elixir/rpn-calculator/HINTS.md @@ -0,0 +1,23 @@ +# Hints + +## General + +- Read about [errors][errors] in the Getting Started guide. +- Read about [`try`][docs-try] in the documentation. + +## 1. Warn the team + +- Allow the operation function to raise its error. +- To invoke a function in a variable, use the `.` operator. + +## 2. Wrap the error + +- Make use of try .. rescue to return the intended result. + +## 3. Pass on the message + +- Make use of try .. rescue to return the intended result. +- The rescue block allows you to pattern match on the error's Module name and also bind the error to a variable. + +[errors]: https://elixir-lang.org/getting-started/try-catch-and-rescue.html#errors +[docs-try]: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#try/1 \ No newline at end of file diff --git a/elixir/rpn-calculator/README.md b/elixir/rpn-calculator/README.md new file mode 100644 index 0000000..0f2de4f --- /dev/null +++ b/elixir/rpn-calculator/README.md @@ -0,0 +1,119 @@ +# RPN Calculator + +Welcome to RPN Calculator 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 + +## Errors + +Errors happen. In Elixir, while people often say to "let it crash", there are times when we need to rescue the function call to a known good state to fulfill a software contract. In some languages, errors are used as a method of control flow, but in Elixir, this pattern is discouraged. We can often recognize functions that may raise an error just by their name: functions that raise errors are to have `!` at the end of their name. This is in comparison with functions that return `{:ok, value}` or `:error`. Look at these library examples: + +```elixir +Map.fetch(%{a: 1}, :b) +# => :error +Map.fetch!(%{a: 1}, :b) +# => raises KeyError +``` + +## Try/Rescue + +Elixir provides a construct for rescuing from errors using `try .. rescue` + +```elixir +try do #1 + raise RuntimeError, "error" #2 +rescue + e in RuntimeError -> :error #3 +end +``` + +Let's examine this construct: + +- **Line 1**, the block is declared with `try`. +- **Line 2**, the function call which may error is placed here, in this case we are calling `raise/2`. +- **Line 3**, in the `rescue` section, we pattern match on the _Module_ name of the error raised + - on the left side of `->`: + - `e` is matched to the error struct. + - `in` is a keyword. + - `RuntimeError` is the error that we want to rescue. + - If we wanted to rescue from all errors, we could use `_` instead of the module name or omit the `in` keyword entirely. + - on the right side: + - the instructions to be executed if the error matches. + +### Error structs + +Errors (sometimes also called "exceptions") that you rescue this way are structs. +Rescuing errors in Elixir is done very rarely. +Usually the rescued error is logged or sent to an external monitoring service, and then reraised. +This means we usually don't care about the internal structure of the specific error struct. + +In the [Exceptions concept][exercism-exceptions] you will learn more about error structs, including how to define your own custom error. + +[exercism-exceptions]: https://exercism.org/tracks/elixir/concepts/exceptions + +## Instructions + +While working at _Instruments of Texas_, you are tasked to work on an experimental Reverse Polish Notation [RPN] calculator written in Elixir. Your team is having a problem with some operations raising errors and crashing the process. You have been tasked to write a function which wraps the operation function so that the errors can be handled more elegantly with idiomatic Elixir code. + +## 1. Warn the team + +Implement the function `calculate!/2` to call the operation function with the stack as the only argument. The operation function is defined elsewhere, but you know that it can either complete successfully or raise an error. + +```elixir +stack = [] +operation = fn _ -> :ok end +RPNCalculator.calculate!(stack, operation) +# => :ok + +stack = [] +operation = fn _ -> raise ArgumentError, "An error occurred" end +RPNCalculator.calculate!(stack, operation) +# => ** (ArgumentError) An error occurred +``` + +> Function names that end in `!` are a warning to programmers that this function may raise an error + +## 2. Wrap the error + +When doing more research you notice that many functions use atoms and tuples to indicate their success/failure. Implement `calculate/2` using this strategy. + +```elixir +stack = [] +operation = fn _ -> "operation completed" end +RPNCalculator.calculate(stack, operation) +# => {:ok, "operation completed"} + +stack = [] +operation = fn _ -> raise ArgumentError, "An error occurred" end +RPNCalculator.calculate(stack, operation) +# => :error +``` + +## 3. Pass on the message + +Some of the errors contain important information that your coworkers need to have to ensure the correct operation of the system. Implement `calculate_verbose/2` to pass on the error message. The error is a struct that has a `:message` field. + +```elixir +stack = [] +operation = fn _ -> "operation completed" end +RPNCalculator.calculate_verbose(stack, operation) +# => {:ok, "operation completed"} + +stack = [] +operation = fn _ -> raise ArgumentError, "An error occurred" end +RPNCalculator.calculate_verbose(stack, operation) +# => {:error, "An error occurred"} +``` + +## Source + +### Created by + +- @neenjaw + +### Contributed to by + +- @angelikatyborska +- @cjmaxik \ No newline at end of file diff --git a/elixir/rpn-calculator/lib/rpn_calculator.ex b/elixir/rpn-calculator/lib/rpn_calculator.ex new file mode 100644 index 0000000..b0e9c6c --- /dev/null +++ b/elixir/rpn-calculator/lib/rpn_calculator.ex @@ -0,0 +1,21 @@ +defmodule RPNCalculator do + def calculate!(stack, operation) do + operation.(stack) + end + + def calculate(stack, operation) do + try do + {:ok, operation.(stack)} + rescue + _ in RuntimeError -> :error + end + end + + def calculate_verbose(stack, operation) do + try do + {:ok, operation.(stack)} + rescue + e in ArgumentError -> {:error, e.message} + end + end +end diff --git a/elixir/rpn-calculator/mix.exs b/elixir/rpn-calculator/mix.exs new file mode 100644 index 0000000..de2dbe1 --- /dev/null +++ b/elixir/rpn-calculator/mix.exs @@ -0,0 +1,28 @@ +defmodule RPNCalculator.MixProject do + use Mix.Project + + def project do + [ + app: :rpn_calculator, + 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 diff --git a/elixir/rpn-calculator/test/rpn_calculator_test.exs b/elixir/rpn-calculator/test/rpn_calculator_test.exs new file mode 100644 index 0000000..36d59c9 --- /dev/null +++ b/elixir/rpn-calculator/test/rpn_calculator_test.exs @@ -0,0 +1,38 @@ +defmodule RPNCalculatorTest do + use ExUnit.Case + + @tag task_id: 1 + test "calculate! returns an :ok atom" do + assert RPNCalculator.calculate!([], fn _ -> :ok end) == :ok + end + + @tag task_id: 1 + test "let it crash" do + assert_raise(RuntimeError, fn -> + RPNCalculator.calculate!([], fn _ -> raise "test error" end) + end) + end + + @tag task_id: 2 + test "calculate returns a tuple" do + assert RPNCalculator.calculate([], fn _ -> "operation completed" end) == + {:ok, "operation completed"} + end + + @tag task_id: 2 + test "rescue the crash, no message" do + assert RPNCalculator.calculate([], fn _ -> raise "test error" end) == :error + end + + @tag task_id: 3 + test "calculate_verbose returns a tuple" do + assert RPNCalculator.calculate_verbose([], fn _ -> "operation completed" end) == + {:ok, "operation completed"} + end + + @tag task_id: 3 + test "rescue the crash, get error tuple with message" do + assert RPNCalculator.calculate_verbose([], fn _ -> raise ArgumentError, "test error" end) == + {:error, "test error"} + end +end diff --git a/elixir/rpn-calculator/test/test_helper.exs b/elixir/rpn-calculator/test/test_helper.exs new file mode 100644 index 0000000..e8677a3 --- /dev/null +++ b/elixir/rpn-calculator/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true, seed: 0) diff --git a/elixir/secret-handshake/.exercism/config.json b/elixir/secret-handshake/.exercism/config.json new file mode 100644 index 0000000..05accf8 --- /dev/null +++ b/elixir/secret-handshake/.exercism/config.json @@ -0,0 +1,27 @@ +{ + "authors": [ + "DoggettCK" + ], + "contributors": [ + "angelikatyborska", + "Cohen-Carlisle", + "devonestes", + "mlopes", + "neenjaw", + "sotojuan" + ], + "files": { + "solution": [ + "lib/secret_handshake.ex" + ], + "test": [ + "test/secret_handshake_test.exs" + ], + "example": [ + ".meta/example.ex" + ] + }, + "blurb": "Given a decimal number, convert it to the appropriate sequence of events for a secret handshake.", + "source": "Bert, in Mary Poppins", + "source_url": "http://www.imdb.com/title/tt0058331/quotes/qt0437047" +} diff --git a/elixir/secret-handshake/.exercism/metadata.json b/elixir/secret-handshake/.exercism/metadata.json new file mode 100644 index 0000000..9c97efd --- /dev/null +++ b/elixir/secret-handshake/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"secret-handshake","id":"4b8f23d5e55540c2be5440fc65a31828","url":"https://exercism.org/tracks/elixir/exercises/secret-handshake","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/secret-handshake/.formatter.exs b/elixir/secret-handshake/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/secret-handshake/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/secret-handshake/.gitignore b/elixir/secret-handshake/.gitignore new file mode 100644 index 0000000..5528e77 --- /dev/null +++ b/elixir/secret-handshake/.gitignore @@ -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"). +secret_handshake-*.tar + diff --git a/elixir/secret-handshake/HELP.md b/elixir/secret-handshake/HELP.md new file mode 100644 index 0000000..2ecf33f --- /dev/null +++ b/elixir/secret-handshake/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/secret_handshake.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/secret-handshake/HINTS.md b/elixir/secret-handshake/HINTS.md new file mode 100644 index 0000000..445888f --- /dev/null +++ b/elixir/secret-handshake/HINTS.md @@ -0,0 +1,9 @@ +# Hints + +## General + +- Use `Bitwise` (or div/rem). +- If you use `Bitwise`, an easy way to see if a particular bit is set is to compare +the binary AND (`&&&`) of a set of bits with the particular bit pattern you +want to check, and determine if the result is the same as the pattern you're +checking. \ No newline at end of file diff --git a/elixir/secret-handshake/README.md b/elixir/secret-handshake/README.md new file mode 100644 index 0000000..15b3137 --- /dev/null +++ b/elixir/secret-handshake/README.md @@ -0,0 +1,52 @@ +# Secret Handshake + +Welcome to Secret Handshake 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 :) + +## Instructions + +> There are 10 types of people in the world: Those who understand +> binary, and those who don't. + +You and your fellow cohort of those in the "know" when it comes to +binary decide to come up with a secret "handshake". + +```text +00001 = wink +00010 = double blink +00100 = close your eyes +01000 = jump + + +10000 = Reverse the order of the operations in the secret handshake. +``` + +Given a decimal number, convert it to the appropriate sequence of events for a secret handshake. + +Here's a couple of examples: + +Given the decimal input 3, the function would return the array +["wink", "double blink"] because the decimal number 3 is 2+1 in powers of two and thus `11` in binary. + +Let's now examine the input 19 which is 16+2+1 in powers of two and thus `10011` in binary. +Recalling that the addition of 16 (`10000` in binary) reverses an array and that we already know what array is returned given input 3, the array returned for input 19 is ["double blink", "wink"]. + +## Source + +### Created by + +- @DoggettCK + +### Contributed to by + +- @angelikatyborska +- @Cohen-Carlisle +- @devonestes +- @mlopes +- @neenjaw +- @sotojuan + +### Based on + +Bert, in Mary Poppins - http://www.imdb.com/title/tt0058331/quotes/qt0437047 \ No newline at end of file diff --git a/elixir/secret-handshake/foo.py b/elixir/secret-handshake/foo.py new file mode 100644 index 0000000..5e825e2 --- /dev/null +++ b/elixir/secret-handshake/foo.py @@ -0,0 +1,13 @@ +class Mewto: + def hello(self): + """ + ASDF + """ + + return 2 + 4 + + def bar(self, a, b): + return a + b + +def poke(a, b): + return a * b diff --git a/elixir/secret-handshake/lib/secret_handshake.ex b/elixir/secret-handshake/lib/secret_handshake.ex new file mode 100644 index 0000000..c9399ef --- /dev/null +++ b/elixir/secret-handshake/lib/secret_handshake.ex @@ -0,0 +1,38 @@ +defmodule SecretHandshake do + @doc """ + Determine the actions of a secret handshake based on the binary + representation of the given `code`. + + If the following bits are set, include the corresponding action in your list + of commands, in order from lowest to highest. + + 1 = wink + 10 = double blink + 100 = close your eyes + 1000 = jump + + 10000 = Reverse the order of the operations in the secret handshake + """ + def commands(code) do + code + |> Integer.digits(2) + |> Enum.reverse() + |> Enum.with_index() + |> Enum.reduce([], fn {bit, index}, acc -> + if bit == 1 do + add_action(index, acc) + else + acc + end + end) + |> Enum.reverse() + end + + + defp add_action(0, acc), do: ["wink" | acc] + defp add_action(1, acc), do: ["double blink" | acc] + defp add_action(2, acc), do: ["close your eyes" | acc] + defp add_action(3, acc), do: ["jump" | acc] + defp add_action(4, acc), do: Enum.reverse(acc) + defp add_action(_, acc), do: acc +end diff --git a/elixir/secret-handshake/mix.exs b/elixir/secret-handshake/mix.exs new file mode 100644 index 0000000..ec009a9 --- /dev/null +++ b/elixir/secret-handshake/mix.exs @@ -0,0 +1,28 @@ +defmodule SecretHandshake.MixProject do + use Mix.Project + + def project do + [ + app: :secret_handshake, + 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 diff --git a/elixir/secret-handshake/tagbardebug.log b/elixir/secret-handshake/tagbardebug.log new file mode 100644 index 0000000..e915cd6 --- /dev/null +++ b/elixir/secret-handshake/tagbardebug.log @@ -0,0 +1,436 @@ + + +NVIM v0.8.0-dev-805-g512e0441f +Build type: RelWithDebInfo +LuaJIT 2.1.0-beta3 +Compilation: /Applications/Xcode_13.2.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -DNVIM_TS_HAS_SET_MATCH_LIMIT -DNVIM_TS_HAS_SET_ALLOCATOR -O2 -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wdouble-promotion -Wmissing-noreturn -Wmissing-format-attribute -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=always -DINCLUDE_GENERATED_DECLARATIONS -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/Users/runner/work/neovim/neovim/build/cmake.config -I/Users/runner/work/neovim/neovim/src -I/Users/runner/work/neovim/neovim/.deps/usr/include -I/Applications/Xcode_13.2.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/usr/include -I/Library/Frameworks/Mono.framework/Headers -I/Users/runner/work/neovim/neovim/build/src/nvim/auto -I/Users/runner/work/neovim/neovim/build/include +Compiled by runner@Mac-1660106808584.local + +Features: +acl +iconv +tui +See ":help feature-compile" + + system vimrc file: "$VIM/sysinit.vim" + fall-back for $VIM: "/share/nvim" + +Run :checkhealth for more info1970-01-23 07:50:54.545526: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:50:54.545793: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:50:54.546213: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:50:54.546474: Unsupported filetype: elixir +1970-01-23 07:50:54.546619: Not a valid file, stopping processing +1970-01-23 07:51:12.009487: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:51:12.009747: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:12.010176: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:51:12.010409: Unsupported filetype: elixir +1970-01-23 07:51:12.010536: Not a valid file, stopping processing +1970-01-23 07:51:21.197657: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:51:21.197919: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:21.198338: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:51:21.198599: Unsupported filetype: elixir +1970-01-23 07:51:21.198770: Not a valid file, stopping processing +1970-01-23 07:51:22.513026: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:22.513248: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:22.513714: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:22.513883: File not readable +1970-01-23 07:51:22.514009: Not a valid file, stopping processing +1970-01-23 07:51:22.531720: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:51:22.533156: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:51:22.533297: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:51:22.533478: Empty filename or type +1970-01-23 07:51:22.533608: Not a valid file, stopping processing +1970-01-23 07:51:22.541306: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:51:22.542402: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:51:22.542544: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:51:22.542681: Empty filename or type +1970-01-23 07:51:22.542794: Not a valid file, stopping processing +1970-01-23 07:51:22.843284: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:22.843472: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:22.843896: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:22.844122: File not readable +1970-01-23 07:51:22.844228: Not a valid file, stopping processing +1970-01-23 07:51:26.895095: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:26.895330: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:26.895465: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:26.895614: File not readable +1970-01-23 07:51:26.895733: Not a valid file, stopping processing +1970-01-23 07:51:27.704415: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:27.704644: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:27.705058: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:27.705219: File not readable +1970-01-23 07:51:27.705339: Not a valid file, stopping processing +1970-01-23 07:51:28.231705: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:28.231926: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:28.232274: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:28.232477: File not readable +1970-01-23 07:51:28.232603: Not a valid file, stopping processing +1970-01-23 07:51:29.525878: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:29.526208: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:29.526655: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:29.526909: File not readable +1970-01-23 07:51:29.527050: Not a valid file, stopping processing +1970-01-23 07:51:29.761982: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:29.762209: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:29.762631: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:29.762812: File not readable +1970-01-23 07:51:29.762946: Not a valid file, stopping processing +1970-01-23 07:51:30.089119: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:30.089348: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:30.089768: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:30.089937: File not readable +1970-01-23 07:51:30.090062: Not a valid file, stopping processing +1970-01-23 07:51:33.037250: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:33.037478: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:33.037834: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:33.037987: File not readable +1970-01-23 07:51:33.038109: Not a valid file, stopping processing +1970-01-23 07:51:34.692830: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:34.693068: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:34.693200: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:34.693380: File not readable +1970-01-23 07:51:34.693497: Not a valid file, stopping processing +1970-01-23 07:51:37.112779: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.113064: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:37.113481: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.113666: File not readable +1970-01-23 07:51:37.113814: Not a valid file, stopping processing +1970-01-23 07:51:37.202667: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.202894: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:37.203293: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.203448: File not readable +1970-01-23 07:51:37.203644: Not a valid file, stopping processing +1970-01-23 07:51:37.278318: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.278513: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:37.278921: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.279058: File not readable +1970-01-23 07:51:37.279178: Not a valid file, stopping processing +1970-01-23 07:51:37.371581: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.371812: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:37.372242: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.372414: File not readable +1970-01-23 07:51:37.372541: Not a valid file, stopping processing +1970-01-23 07:51:37.452844: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.453042: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:37.453431: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.453581: File not readable +1970-01-23 07:51:37.453689: Not a valid file, stopping processing +1970-01-23 07:51:37.621710: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.621947: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:37.622337: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.622502: File not readable +1970-01-23 07:51:37.622626: Not a valid file, stopping processing +1970-01-23 07:51:37.706168: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.706392: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:37.706815: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.706981: File not readable +1970-01-23 07:51:37.707101: Not a valid file, stopping processing +1970-01-23 07:51:37.865252: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.865507: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:37.865902: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.866088: File not readable +1970-01-23 07:51:37.866227: Not a valid file, stopping processing +1970-01-23 07:51:37.948602: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.948822: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:37.949238: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:37.949398: File not readable +1970-01-23 07:51:37.949516: Not a valid file, stopping processing +1970-01-23 07:51:38.628586: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:38.628816: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:38.629288: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:38.629458: File not readable +1970-01-23 07:51:38.629585: Not a valid file, stopping processing +1970-01-23 07:51:38.881475: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:38.881707: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:38.882120: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:38.882281: File not readable +1970-01-23 07:51:38.882400: Not a valid file, stopping processing +1970-01-23 07:51:38.953962: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:38.954223: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:38.954628: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:38.954828: File not readable +1970-01-23 07:51:38.954970: Not a valid file, stopping processing +1970-01-23 07:51:39.037547: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:39.037807: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:39.038227: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:39.038423: File not readable +1970-01-23 07:51:39.038570: Not a valid file, stopping processing +1970-01-23 07:51:39.993100: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:39.993357: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:39.993779: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:39.994065: File not readable +1970-01-23 07:51:39.994220: Not a valid file, stopping processing +1970-01-23 07:51:40.814052: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:40.814311: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:40.814717: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:40.814907: File not readable +1970-01-23 07:51:40.815048: Not a valid file, stopping processing +1970-01-23 07:51:41.397997: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:41.398248: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:41.398677: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:41.398858: File not readable +1970-01-23 07:51:41.398976: Not a valid file, stopping processing +1970-01-23 07:51:41.489330: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:41.489534: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:41.489936: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:41.490077: File not readable +1970-01-23 07:51:41.490213: Not a valid file, stopping processing +1970-01-23 07:51:41.571945: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:41.572140: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:41.572508: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:41.572655: File not readable +1970-01-23 07:51:41.572760: Not a valid file, stopping processing +1970-01-23 07:51:41.657112: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:41.657345: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:41.657736: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:41.657909: File not readable +1970-01-23 07:51:41.658029: Not a valid file, stopping processing +1970-01-23 07:51:41.732590: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:41.732849: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:41.733266: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:51:41.733463: File not readable +1970-01-23 07:51:41.733605: Not a valid file, stopping processing +1970-01-23 07:51:42.480772: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:51:42.481003: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:42.481137: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:51:42.481329: Unsupported filetype: elixir +1970-01-23 07:51:42.481443: Not a valid file, stopping processing +1970-01-23 07:51:42.797252: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:51:42.797508: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:42.797964: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:51:42.798222: Unsupported filetype: elixir +1970-01-23 07:51:42.798368: Not a valid file, stopping processing +1970-01-23 07:51:46.209112: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:51:46.209350: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:46.209741: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:51:46.209974: Unsupported filetype: elixir +1970-01-23 07:51:46.210104: Not a valid file, stopping processing +1970-01-23 07:51:55.247060: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:51:55.247330: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:51:55.247742: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:51:55.248012: Unsupported filetype: elixir +1970-01-23 07:51:55.248174: Not a valid file, stopping processing +1970-01-23 07:52:21.931664: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:52:21.931948: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:52:21.932367: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:52:21.932632: Unsupported filetype: elixir +1970-01-23 07:52:21.932779: Not a valid file, stopping processing +1970-01-23 07:52:28.598961: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:52:28.599298: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:52:28.599492: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:52:28.599742: Unsupported filetype: elixir +1970-01-23 07:52:28.599885: Not a valid file, stopping processing +1970-01-23 07:52:29.097393: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:52:29.097656: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:52:29.098082: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:52:29.098344: Unsupported filetype: elixir +1970-01-23 07:52:29.098493: Not a valid file, stopping processing +1970-01-23 07:52:30.923631: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:52:30.923915: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:52:30.924330: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:52:30.924612: Unsupported filetype: elixir +1970-01-23 07:52:30.924758: Not a valid file, stopping processing +1970-01-23 07:52:32.611722: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:52:32.611989: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:52:32.612417: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:52:32.612682: Unsupported filetype: elixir +1970-01-23 07:52:32.612828: Not a valid file, stopping processing +1970-01-23 07:52:50.465095: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:52:50.465311: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:52:50.465449: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:52:50.465598: File not readable +1970-01-23 07:52:50.465712: Not a valid file, stopping processing +1970-01-23 07:52:50.474613: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:52:50.475677: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:52:50.475810: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:52:50.475946: Empty filename or type +1970-01-23 07:52:50.476061: Not a valid file, stopping processing +1970-01-23 07:52:50.484128: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:52:50.485038: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:52:50.485168: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:52:50.485311: Empty filename or type +1970-01-23 07:52:50.485493: Not a valid file, stopping processing +1970-01-23 07:52:50.566005: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:52:50.566245: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:52:50.566455: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:52:50.566662: File not readable +1970-01-23 07:52:50.566815: Not a valid file, stopping processing +1970-01-23 07:52:54.207757: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:52:54.207963: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:52:54.208081: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:52:54.208289: Unsupported filetype: elixir +1970-01-23 07:52:54.208502: Not a valid file, stopping processing +1970-01-23 07:52:54.525863: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:52:54.526124: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:52:54.526540: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:52:54.526800: Unsupported filetype: elixir +1970-01-23 07:52:54.526959: Not a valid file, stopping processing +1970-01-23 07:53:14.678725: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:53:14.678960: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:14.679513: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:53:14.679761: File not readable +1970-01-23 07:53:14.679894: Not a valid file, stopping processing +1970-01-23 07:53:14.689713: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:53:14.690979: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:53:14.691125: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:53:14.691251: Empty filename or type +1970-01-23 07:53:14.691412: Not a valid file, stopping processing +1970-01-23 07:53:14.699950: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:53:14.700813: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:53:14.700947: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:53:14.701119: Empty filename or type +1970-01-23 07:53:14.701247: Not a valid file, stopping processing +1970-01-23 07:53:14.732048: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:53:14.732250: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:14.732369: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:53:14.732499: File not readable +1970-01-23 07:53:14.732603: Not a valid file, stopping processing +1970-01-23 07:53:19.127773: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:19.128004: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:19.128135: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:19.128413: Unsupported filetype: elixir +1970-01-23 07:53:19.128547: Not a valid file, stopping processing +1970-01-23 07:53:19.444483: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:19.444746: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:19.445156: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:19.445423: Unsupported filetype: elixir +1970-01-23 07:53:19.445710: Not a valid file, stopping processing +1970-01-23 07:53:25.873015: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:25.873284: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:25.873781: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:25.874066: Unsupported filetype: elixir +1970-01-23 07:53:25.874222: Not a valid file, stopping processing +1970-01-23 07:53:29.354945: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:53:29.355158: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:29.355290: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:53:29.355473: File not readable +1970-01-23 07:53:29.355598: Not a valid file, stopping processing +1970-01-23 07:53:29.364950: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:53:29.365824: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:53:29.365969: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:53:29.366103: Empty filename or type +1970-01-23 07:53:29.366213: Not a valid file, stopping processing +1970-01-23 07:53:29.374065: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:53:29.375150: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:53:29.375281: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:53:29.375400: Empty filename or type +1970-01-23 07:53:29.375508: Not a valid file, stopping processing +1970-01-23 07:53:32.250657: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:32.250942: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:32.251106: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:32.251328: Unsupported filetype: elixir +1970-01-23 07:53:32.251461: Not a valid file, stopping processing +1970-01-23 07:53:32.566748: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:32.567013: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:32.567437: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:32.567690: Unsupported filetype: elixir +1970-01-23 07:53:32.567834: Not a valid file, stopping processing +1970-01-23 07:53:34.266794: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:53:34.267033: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:34.267466: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:53:34.267637: File not readable +1970-01-23 07:53:34.267763: Not a valid file, stopping processing +1970-01-23 07:53:34.276964: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:53:34.277885: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:53:34.278043: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:53:34.278180: Empty filename or type +1970-01-23 07:53:34.278294: Not a valid file, stopping processing +1970-01-23 07:53:34.286377: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:53:34.287238: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:53:34.287365: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:53:34.287557: Empty filename or type +1970-01-23 07:53:34.287688: Not a valid file, stopping processing +1970-01-23 07:53:35.704514: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:35.704996: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:35.705192: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:35.705502: Unsupported filetype: elixir +1970-01-23 07:53:35.705678: Not a valid file, stopping processing +1970-01-23 07:53:36.021286: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:36.021548: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:36.021963: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:36.022222: Unsupported filetype: elixir +1970-01-23 07:53:36.022367: Not a valid file, stopping processing +1970-01-23 07:53:37.179853: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:53:37.180065: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:37.180630: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:53:37.180908: File not readable +1970-01-23 07:53:37.181130: Not a valid file, stopping processing +1970-01-23 07:53:37.190315: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:53:37.190774: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:53:37.190923: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:53:37.191069: Empty filename or type +1970-01-23 07:53:37.191190: Not a valid file, stopping processing +1970-01-23 07:53:37.198892: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:53:37.199995: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:53:37.200125: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:53:37.200319: Empty filename or type +1970-01-23 07:53:37.200450: Not a valid file, stopping processing +1970-01-23 07:53:39.877998: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:39.878241: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:39.878378: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:39.878598: Unsupported filetype: elixir +1970-01-23 07:53:39.878724: Not a valid file, stopping processing +1970-01-23 07:53:40.202477: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:40.202853: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:40.203206: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:40.203469: Unsupported filetype: elixir +1970-01-23 07:53:40.203616: Not a valid file, stopping processing +1970-01-23 07:53:43.256500: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:53:43.256718: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:43.257253: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:53:43.257437: File not readable +1970-01-23 07:53:43.257568: Not a valid file, stopping processing +1970-01-23 07:53:43.266879: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:53:43.268084: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:53:43.268236: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:53:43.268374: Empty filename or type +1970-01-23 07:53:43.268494: Not a valid file, stopping processing +1970-01-23 07:53:43.276375: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:53:43.276758: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:53:43.276894: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:53:43.277020: Empty filename or type +1970-01-23 07:53:43.277233: Not a valid file, stopping processing +1970-01-23 07:53:45.548767: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:45.549069: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:45.549226: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:45.549489: Unsupported filetype: elixir +1970-01-23 07:53:45.549614: Not a valid file, stopping processing +1970-01-23 07:53:45.948930: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:45.949194: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:45.949616: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:45.949942: Unsupported filetype: elixir +1970-01-23 07:53:45.950121: Not a valid file, stopping processing +1970-01-23 07:53:49.994612: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:53:49.994825: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:49.995328: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/] +1970-01-23 07:53:49.995495: File not readable +1970-01-23 07:53:49.995619: Not a valid file, stopping processing +1970-01-23 07:53:50.004546: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:53:50.005689: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:53:50.005828: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopePrompt] +1970-01-23 07:53:50.005969: Empty filename or type +1970-01-23 07:53:50.006083: Not a valid file, stopping processing +1970-01-23 07:53:50.013752: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:53:50.014793: Vim filetype: '', sanitized filetype: '' +1970-01-23 07:53:50.014921: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/TelescopeResults] +1970-01-23 07:53:50.015112: Empty filename or type +1970-01-23 07:53:50.015244: Not a valid file, stopping processing +1970-01-23 07:53:54.705663: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:54.705898: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:54.706108: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:54.706349: Unsupported filetype: elixir +1970-01-23 07:53:54.706478: Not a valid file, stopping processing +1970-01-23 07:53:55.029265: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:55.029574: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:53:55.029976: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:53:55.030240: Unsupported filetype: elixir +1970-01-23 07:53:55.030387: Not a valid file, stopping processing +1970-01-23 07:54:00.232866: ToggleWindow called +1970-01-23 07:54:00.233219: CloseWindow called +1970-01-23 07:54:00.233777: goto_win(): 2wincmd w, 0 +1970-01-23 07:54:00.237724: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/__Tagbar__.1] +1970-01-23 07:54:00.238468: In Tagbar window, stopping processing +1970-01-23 07:54:00.245100: AutoUpdate called [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:54:00.245372: Vim filetype: 'elixir', sanitized filetype: 'elixir' +1970-01-23 07:54:00.245538: Checking if file is valid [/Users/fbecker18/Exercism/elixir/secret-handshake/lib/secret_handshake.ex] +1970-01-23 07:54:00.245747: Unsupported filetype: elixir +1970-01-23 07:54:00.245869: Not a valid file, stopping processing +1970-01-23 07:54:00.246187: goto_win(): 1wincmd w, 0 +1970-01-23 07:54:00.246434: CloseWindow finished diff --git a/elixir/secret-handshake/tags b/elixir/secret-handshake/tags new file mode 100644 index 0000000..9a9f07e --- /dev/null +++ b/elixir/secret-handshake/tags @@ -0,0 +1,1696 @@ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ +!_TAG_PROGRAM_NAME Exuberant Ctags // +!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ +!_TAG_PROGRAM_VERSION 5.8 // +CODE_VERSION .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^-define(CODE_VERSION, "1.4").$/;" d +DEPS .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/rebar3_docsh.erl /^-define(DEPS, [{default, compile}]).$/;" d +DESC .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/rebar3_docsh.erl /^-define(DESC, "Store modules' documentation in Docs chunks according to EEP-48.\\n"$/;" d +DOCSH_STACKTRACE_H .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_stacktrace.hrl /^-define(DOCSH_STACKTRACE_H, true).$/;" d +INCLUDE1_CONST .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erl2ex/test/files/include1.hrl /^-define(INCLUDE1_CONST, 1).$/;" d +INCLUDE2_CONST .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erl2ex/test/files/files2/include2.hrl /^-define(INCLUDE2_CONST, 2).$/;" d +INCLUDE3_CONST .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erl2ex/test/files/include3.hrl /^-define(INCLUDE3_CONST, 3).$/;" d +IS_OPT_SPEC .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^-define(IS_OPT_SPEC(Opt), (tuple_size(Opt) =:= ?OPT_HELP)).$/;" d +IS_WHITESPACE .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^-define(IS_WHITESPACE(Char), ((Char) =:= $\\s orelse (Char) =:= $\\t orelse$/;" d +LINE_LENGTH .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^-define(LINE_LENGTH, 75).$/;" d +MIN_USAGE_COMMAND_LINE_OPTION_LENGTH .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^-define(MIN_USAGE_COMMAND_LINE_OPTION_LENGTH, 25).$/;" d +Mewto foo.py /^class Mewto:$/;" c +OPT_ARG .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^-define(OPT_ARG, 4).$/;" d +OPT_HELP .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^-define(OPT_HELP, 5).$/;" d +OPT_LONG .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^-define(OPT_LONG, 3).$/;" d +OPT_NAME .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^-define(OPT_NAME, 1).$/;" d +OPT_SHORT .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^-define(OPT_SHORT, 2).$/;" d +PROVIDER .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/rebar3_docsh.erl /^-define(PROVIDER, compile).$/;" d +PRV_ERROR .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/_build/shared/lib/providers/include/providers.hrl /^-define(PRV_ERROR(Reason),$/;" d +PRV_ERROR .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/include/providers.hrl /^-define(PRV_ERROR(Reason),$/;" d +SHORT_DESC .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/rebar3_docsh.erl /^-define(SHORT_DESC, "Store modules' documentation in Docs chunks according to EEP-48").$/;" d +a2b .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^-define(a2b(A), atom_to_binary(A, utf8)).$/;" d +a2b .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_internal.erl /^-define(a2b(A), atom_to_binary(A, utf8)).$/;" d +a2l .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_internal.erl /^-define(a2l(A), atom_to_list(A)).$/;" d +abstract_code .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_beam.erl /^abstract_code(B) ->$/;" f module:docsh_beam +activated .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^activated(path) ->$/;" f module:docsh +activated .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^activated(user_default) ->$/;" f module:docsh +add_chunks .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/rebar3_docsh.erl /^add_chunks(BeamFile, NewChunks) ->$/;" f module:rebar3_docsh +add_custom_help_lines .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^add_custom_help_lines([CustomCols | Tail], PrevMaxOptionLength, Acc) ->$/;" f module:getopt +add_custom_help_lines .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^add_custom_help_lines([], MaxOptionLength, Acc) ->$/;" f module:getopt +add_option_spec_help_lines .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^add_option_spec_help_lines([OptSpec | Tail], PrevMaxOptionLength, Acc) ->$/;" f module:getopt +add_option_spec_help_lines .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^add_option_spec_help_lines([], MaxOptionLength, Acc) ->$/;" f module:getopt +add_option_with_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^add_option_with_arg({Name, _Short, _Long, ArgSpec, _Help} = OptSpec, Arg, OptAcc) ->$/;" f module:getopt +add_option_with_assigned_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^add_option_with_assigned_arg({Name, _Short, _Long, ArgSpec, _Help}, Arg, OptAcc) ->$/;" f module:getopt +add_option_with_implicit_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^add_option_with_implicit_arg({Name, _Short, _Long, ArgSpec, _Help}, OptAcc) ->$/;" f module:getopt +add_option_with_implicit_incrementable_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^add_option_with_implicit_incrementable_arg({Name, _Short, _Long, ArgSpec, _Help}, OptAcc) ->$/;" f module:getopt +adjust_line .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^adjust_line(N, N, _Cs, L) -> L;$/;" f module:lexer +adjust_line .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^adjust_line(T, A, [$\\n|Cs], L) ->$/;" f module:lexer +adjust_line .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^adjust_line(T, A, [_|Cs], L) ->$/;" f module:lexer +all .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers_topo.erl /^all(L) ->$/;" f module:providers_topo +app_beam_files .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/rebar3_docsh.erl /^app_beam_files(App) ->$/;" f module:rebar3_docsh +append_default_options .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^append_default_options([], OptAcc) ->$/;" f module:getopt +append_default_options .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^append_default_options([_Head | Tail], OptAcc) ->$/;" f module:getopt +append_default_options .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^append_default_options([{Name, _Short, _Long, {_Type, DefaultArg}, _Help} | Tail], OptAcc) ->$/;" f module:getopt +are_disjoint .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_internal.erl /^are_disjoint(Info1, Info2) ->$/;" f module:docsh_internal +arg_spec_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^arg_spec_type(Type) when is_atom(Type) ->$/;" f module:getopt +arg_spec_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^arg_spec_type({Type, _DefaultArg}) ->$/;" f module:getopt +attribute .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_beam.erl /^attribute(B, Name) ->$/;" f module:docsh_beam +available .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^available(Beam) ->$/;" f module:docsh_edoc +available .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^available(Beam) ->$/;" f module:docsh_syntax +available_readers .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^available_readers(Beam) ->$/;" f module:docsh_lib +bar foo.py /^ def bar(self, a, b):$/;" m class:Mewto +beam_diff .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^beam_diff(BEAM1, BEAM2) ->$/;" f module:docsh_lib +beam_file .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_beam.erl /^beam_file(B) -> B#docsh_beam.beam_file.$/;" f module:docsh_beam +beam_name .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_beam.erl /^beam_name(BEAMFile) ->$/;" f module:docsh_beam +behaviour_info .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/provider.erl /^behaviour_info(_) ->$/;" f module:provider +behaviour_info .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/provider.erl /^behaviour_info(callbacks) ->$/;" f module:provider +bind .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_beam.erl /^bind(false) -> false.$/;" f module:docsh_beam +bind .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_beam.erl /^bind({ok, V}) -> V;$/;" f module:docsh_beam +check .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^check(OptSpecList, ParsedOpts) when is_list(OptSpecList), is_list(ParsedOpts) ->$/;" f module:getopt +check_source_file .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^check_source_file("\/net" ++ _, false) ->$/;" f module:docsh_lib +check_source_file .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^check_source_file(SourceFile, false) ->$/;" f module:docsh_lib +check_source_file .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^check_source_file(_SourceFile, {ok, File}) ->$/;" f module:docsh_lib +cleanup_preformatted_text .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^cleanup_preformatted_text(Text, _Ctx) ->$/;" f module:docsh_edoc_xmerl +cleanup_text .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^cleanup_text(Text, _Ctx) ->$/;" f module:docsh_edoc_xmerl +cleanup_text .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^cleanup_text() ->$/;" f module:docsh_tracer +commands .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^commands() ->$/;" f module:docsh +compile_info_source_file .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^compile_info_source_file(BEAMFile) ->$/;" f module:docsh_lib +convert .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^convert(Readers, Writer, Beam) ->$/;" f module:docsh_lib +convert_one .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^convert_one({Reader, Mod}) ->$/;" f module:docsh_lib +count_args .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^count_args(Args) ->$/;" f module:docsh_edoc_xmerl +create .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^create(Attrs) ->$/;" f module:providers +cspan .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^cspan(Str, Chars) -> length(element(1,string:take(Str, Chars, true))).$/;" f module:getopt +cspan .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^cspan(Str, Chars) -> string:cspan(Str, Chars).$/;" f module:getopt +debug .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^debug(_, _) -> ok.$/;" f module:docsh_edoc_xmerl +debug .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^debug(Tag, Fmt, Args) ->$/;" f module:docsh_lib +debug_info_v1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^debug_info_v1({debug_info_v1, _, {Forms, _CompileInfo}}) ->$/;" f module:docsh_lib +debug_matching .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^debug_matching(Tags, Tag, Fmt, Args) ->$/;" f module:docsh_lib +default_arg_value_to_string .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^default_arg_value_to_string(Value) ->$/;" f module:getopt +default_arg_value_to_string .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^default_arg_value_to_string(Value) when is_atom(Value) ->$/;" f module:getopt +default_arg_value_to_string .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^default_arg_value_to_string(Value) when is_binary(Value) ->$/;" f module:getopt +default_arg_value_to_string .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^default_arg_value_to_string(Value) when is_float(Value) ->$/;" f module:getopt +default_arg_value_to_string .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^default_arg_value_to_string(Value) when is_integer(Value) ->$/;" f module:getopt +default_formats .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_format.erl /^default_formats() ->$/;" f module:docsh_format +default_writer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^default_writer() ->$/;" f module:docsh_lib +desc .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^desc(Provider) ->$/;" f module:providers +description .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^description(_Name, _Arity, Info, #{lang := Lang}) ->$/;" f module:docsh_docs_v1 +diff .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^diff(["diff", BEAM1, BEAM2]) ->$/;" f module:docsh +dispatch .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^dispatch(edoc, _File, EDoc) -> pp(EDoc);$/;" f module:docsh_edoc +dispatch .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^dispatch(flat, _File, EDoc) -> pp(xmerl:export_simple([EDoc], docsh_edoc_xmerl_flat));$/;" f module:docsh_edoc +dispatch .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^dispatch(html, _File, EDoc) -> io_lib:format("~s", [edoc:layout(EDoc)]);$/;" f module:docsh_edoc +dispatch .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^dispatch(internal, _File, EDoc) -> pp(xmerl:export_simple([EDoc], docsh_edoc_xmerl));$/;" f module:docsh_edoc +dispatch .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^dispatch(otpsgml, _File, EDoc) -> io_lib:format("~s", [xmerl:export_simple([EDoc], xmerl_otpsgml)]);$/;" f module:docsh_edoc +dispatch .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^dispatch(source, File, _EDoc) ->$/;" f module:docsh_edoc +dispatch .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^dispatch(text, _File, EDoc) -> pp(xmerl:export_simple([EDoc], xmerl_text)).$/;" f module:docsh_edoc +dispatch .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^dispatch(xml, _File, EDoc) -> xmerl:export_simple([EDoc], xmerl_xml);$/;" f module:docsh_edoc +dispatch_docs_extraction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^dispatch_docs_extraction(B, always, _) ->$/;" f module:docsh_lib +dispatch_docs_extraction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^dispatch_docs_extraction(B, compile_if_missing, {error, _} = Err) ->$/;" f module:docsh_lib +dispatch_docs_extraction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^dispatch_docs_extraction(B, never, AvailableDocs) ->$/;" f module:docsh_lib +dispatch_docs_extraction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^dispatch_docs_extraction(_, compile_if_missing, {ok, Docs}) ->$/;" f module:docsh_lib +dispatch_docs_extraction_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^dispatch_docs_extraction_(B) ->$/;" f module:docsh_lib +dispatch_lookup .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^dispatch_lookup(Docs, _Mod, [moduledoc]) ->$/;" f module:docsh_docs_v1 +dispatch_lookup .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^dispatch_lookup(Docs, _Mod, [type]) ->$/;" f module:docsh_docs_v1 +dispatch_lookup .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^dispatch_lookup(Docs, {_Mod, Name, Arity}, Kinds)$/;" f module:docsh_docs_v1 +dispatch_lookup .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^dispatch_lookup(Docs, {_Mod, Name, Arity}, [doc, type]) ->$/;" f module:docsh_docs_v1 +display_help .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^display_help(Help) ->$/;" f module:providers +dl_item .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^dl_item(Prefix, Lines) ->$/;" f module:docsh_edoc_xmerl +do .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/rebar3_docsh.erl /^do(State) ->$/;" f module:rebar3_docsh +do .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^do(Provider, State) ->$/;" f module:providers +do_get_docs .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^do_get_docs(B) ->$/;" f module:docsh_lib +do_make_docs .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^do_make_docs(Beam) ->$/;" f module:docsh_lib +docs .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_beam.erl /^docs(#docsh_beam{} = B) ->$/;" f module:docsh_beam +docs_v1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^-record(docs_v1, {anno,$/;" r +docs_v1_default .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^docs_v1_default() ->$/;" f module:docsh_docs_v1 +docsh .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^-module(docsh).$/;" m +docsh_beam .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_beam.erl /^-module(docsh_beam).$/;" m +docsh_beam .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_beam.erl /^-record(docsh_beam, {name, beam_file, source_file}).$/;" r +docsh_docs_v1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^-module(docsh_docs_v1).$/;" m +docsh_edoc .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^-module(docsh_edoc).$/;" m +docsh_edoc_xmerl .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^-module(docsh_edoc_xmerl).$/;" m +docsh_edoc_xmerl_flat .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl_flat.erl /^-module(docsh_edoc_xmerl_flat).$/;" m +docsh_erl .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^-module(docsh_erl).$/;" m +docsh_format .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_format.erl /^-module(docsh_format).$/;" m +docsh_internal .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_internal.erl /^-module(docsh_internal).$/;" m +docsh_lib .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^-module(docsh_lib).$/;" m +docsh_reader .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_reader.erl /^-module(docsh_reader).$/;" m +docsh_syntax .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^-module(docsh_syntax).$/;" m +docsh_tracer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^-module(docsh_tracer).$/;" m +docsh_user_default .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_user_default.erl /^-module(docsh_user_default).$/;" m +docsh_writer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_writer.erl /^-module(docsh_writer).$/;" m +ebin_prefix .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^ebin_prefix(BEAMFile) ->$/;" f module:docsh_lib +element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^element(Element) ->$/;" f module:docsh_tracer +end_block .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^end_block(Doc) -> end_block([{br}, {br} | lists:reverse(lists:flatten(Doc))], []).$/;" f module:docsh_edoc_xmerl +end_block .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^end_block([Node | Doc], Acc) -> end_block(Doc, [Node | Acc]).$/;" f module:docsh_edoc_xmerl +end_block .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^end_block([], Acc) -> Acc;$/;" f module:docsh_edoc_xmerl +end_block .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^end_block([{br} | Doc], [] = Acc) -> end_block(Doc, [{br} | Acc]);$/;" f module:docsh_edoc_xmerl +end_block .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^end_block([{br} | Doc], [{br}, {br}] = Acc) -> end_block(Doc, Acc);$/;" f module:docsh_edoc_xmerl +end_block .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^end_block([{br} | Doc], [{br}] = Acc) -> end_block(Doc, [{br} | Acc]);$/;" f module:docsh_edoc_xmerl +enum .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^enum(List) -> lists:zip(lists:seq(1, length(List)), List).$/;" f module:docsh +enum .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^enum(L) ->$/;" f module:docsh_tracer +enumerate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^enumerate(List) ->$/;" f module:docsh_edoc_xmerl +expand_env_var .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^expand_env_var(CmdLine) ->$/;" f module:getopt +expand_env_var .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^expand_env_var(Prefix, CmdLine, Acc) ->$/;" f module:getopt +expand_env_var .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^expand_env_var(Prefix, EndMark, [Char | Tail], Acc)$/;" f module:getopt +expand_env_var .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^expand_env_var(Prefix, EndMark, [EndMark | Tail], Acc) ->$/;" f module:getopt +expand_env_var .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^expand_env_var(Prefix, [Char | Tail], Acc)$/;" f module:getopt +expand_env_var .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^expand_env_var(Prefix, _EndMark, CmdLine, Acc) ->$/;" f module:getopt +expand_hooks .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^expand_hooks([Provider | Tail], TargetProviders, Providers) ->$/;" f module:providers +expand_hooks .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^expand_hooks([], TargetProviders, _Providers) ->$/;" f module:providers +fargs .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^fargs(A) -> io_lib:format("~p", [A]). % last or only arg$/;" f module:docsh_tracer +fargs .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^fargs(Arity) when is_integer(Arity) -> integer_to_list(Arity);$/;" f module:docsh_tracer +fargs .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^fargs([A]) -> io_lib:format("~p", [A]); %% last arg$/;" f module:docsh_tracer +fargs .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^fargs([A|Args]) -> [io_lib:format("~p,", [A]) | fargs(Args)];$/;" f module:docsh_tracer +fargs .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^fargs([]) -> [];$/;" f module:docsh_tracer +fetch_items .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^fetch_items(AllItems, Kind, Name, Arity) ->$/;" f module:docsh_docs_v1 +ffunc .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^ffunc(X) -> io_lib:format("~p", [X]).$/;" f module:docsh_tracer +ffunc .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^ffunc({M,F,Argl}) when is_list(Argl) ->$/;" f module:docsh_tracer +ffunc .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^ffunc({M,F,Arity}) ->$/;" f module:docsh_tracer +find_non_option_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^find_non_option_arg([], _Pos) ->$/;" f module:getopt +find_non_option_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^find_non_option_arg([_Head | Tail], Pos) ->$/;" f module:getopt +find_non_option_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^find_non_option_arg([{_Name, undefined, undefined, _ArgSpec, _Help} = OptSpec | _Tail], 0) ->$/;" f module:getopt +find_non_option_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^find_non_option_arg([{_Name, undefined, undefined, _ArgSpec, _Help} | Tail], Pos) ->$/;" f module:getopt +flatten_if_state .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^flatten_if_state(Arg) -> Arg.$/;" f module:docsh_tracer +flatten_if_state .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^flatten_if_state(State) when is_tuple(State), element(1, State) == state -> state;$/;" f module:docsh_tracer +format .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^format(DocItems, Mod, Kinds, Lang) -> format_items(Mod, DocItems, Kinds, Lang).$/;" f module:docsh_erl +format .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^format(DocItems, {Mod, _, _}, Kinds, Lang) -> format_items(Mod, DocItems, Kinds, Lang);$/;" f module:docsh_erl +format .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^format([DocItem], Mod, [moduledoc], Lang) -> format_module_doc(Mod, maps:get(Lang, DocItem));$/;" f module:docsh_erl +format .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^format(Attr) ->$/;" f module:docsh_syntax +format .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^format(#provider{name=Name}) ->$/;" f module:providers +format_call .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^format_call({trace, Pid, call, {M, F, Args}} = _Trace) ->$/;" f module:docsh_tracer +format_content .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_content(Content, Ctx) ->$/;" f module:docsh_edoc_xmerl +format_content .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^format_content() ->$/;" f module:docsh_tracer +format_content_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_content_(#xmlComment{}, _Ctx) -> [];$/;" f module:docsh_edoc_xmerl +format_content_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_content_(#xmlDecl{}, _Ctx) -> [];$/;" f module:docsh_edoc_xmerl +format_content_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_content_(#xmlElement{name = Name, content = Content} = E, Ctx) ->$/;" f module:docsh_edoc_xmerl +format_content_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_content_(#xmlPI{}, _Ctx) -> [];$/;" f module:docsh_edoc_xmerl +format_content_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_content_(#xmlText{} = T, Ctx) ->$/;" f module:docsh_edoc_xmerl +format_edoc .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^format_edoc(EDoc, Ctx) ->$/;" f module:docsh_edoc +format_edoc .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_edoc(Content, Ctx) ->$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(_, #xmlElement{}, Lines, _Ctx) ->$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(code, #xmlElement{}, Lines, _Ctx) ->$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(dd, #xmlElement{}, Lines, _Ctx) ->$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(dl, #xmlElement{}, Lines, _Ctx) ->$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(dt, #xmlElement{}, Lines, _Ctx) ->$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(h1, #xmlElement{} = E, Lines, Ctx) -> format_header(E, Lines, Ctx);$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(h2, #xmlElement{} = E, Lines, Ctx) -> format_header(E, Lines, Ctx);$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(h3, #xmlElement{} = E, Lines, Ctx) -> format_header(E, Lines, Ctx);$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(h4, #xmlElement{} = E, Lines, Ctx) -> format_header(E, Lines, Ctx);$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(h5, #xmlElement{} = E, Lines, Ctx) -> format_header(E, Lines, Ctx);$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(h6, #xmlElement{} = E, Lines, Ctx) -> format_header(E, Lines, Ctx);$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(hgroup, _, _Lines, _Ctx) -> [];$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(li, #xmlElement{}, Lines, _Ctx) ->$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(ol, #xmlElement{} = E, ListItems, Ctx) ->$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(p, #xmlElement{}, Lines, _Ctx) ->$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(pre, #xmlElement{}, Lines, _Ctx) ->$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_element(ul, #xmlElement{} = E, ListItems, Ctx) ->$/;" f module:docsh_edoc_xmerl +format_element .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^format_element() ->$/;" f module:docsh_tracer +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^format_error(Reason) when is_list(Reason);$/;" f module:docsh_lib +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^format_error(docs_present) ->$/;" f module:docsh_lib +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^format_error(no_debug_info_no_src) ->$/;" f module:docsh_lib +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^format_error({error, Reason, Stacktrace}) ->$/;" f module:docsh_lib +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^format_error({no_debug_info, Mod}) ->$/;" f module:docsh_lib +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^format_error({no_src, Mod}) ->$/;" f module:docsh_lib +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/rebar3_docsh.erl /^format_error(Reason) ->$/;" f module:rebar3_docsh +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^format_error({illegal,S}) -> ["illegal characters ",io_lib:write_string(S)];$/;" f module:lexer +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^format_error({user,S}) -> S.$/;" f module:lexer +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^format_error(Message) ->$/;" f module:parser +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^format_error(OptSpecList, {error, Reason}) ->$/;" f module:getopt +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^format_error(OptSpecList, {missing_required_option, Name}) ->$/;" f module:getopt +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^format_error(_OptSpecList, {Reason, Data}) ->$/;" f module:getopt +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^format_error(_OptSpecList, {invalid_option, OptStr}) ->$/;" f module:getopt +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^format_error(_OptSpecList, {invalid_option_arg, OptStr}) ->$/;" f module:getopt +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^format_error(_OptSpecList, {invalid_option_arg, {Name, Arg}}) ->$/;" f module:getopt +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^format_error(#provider{module=Mod}, Error) ->$/;" f module:providers +format_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^format_error({provider_not_found, Namespace, ProviderName}) ->$/;" f module:providers +format_header .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_header(#xmlElement{name = Name}, Lines, _Ctx) ->$/;" f module:docsh_edoc_xmerl +format_item .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^format_item(Mod, Item, Kinds, Lang) ->$/;" f module:docsh_erl +format_items .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^format_items(Mod, Items, Kinds, Lang) ->$/;" f module:docsh_erl +format_maybe_doc .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^format_maybe_doc(Doc, Lang) ->$/;" f module:docsh_erl +format_maybe_doc .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^format_maybe_doc(hidden, _) -> docsh_format:item_doc_hidden();$/;" f module:docsh_erl +format_maybe_doc .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^format_maybe_doc(none, _) -> docsh_format:item_doc_not_available();$/;" f module:docsh_erl +format_module_doc .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^format_module_doc(Mod, Doc) ->$/;" f module:docsh_erl +format_return_from .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^format_return_from({trace, Pid, return_from, {M, F, Arity}, Ret} = _Trace) ->$/;" f module:docsh_tracer +format_text .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^format_text(TextSubtree) ->$/;" f module:docsh_edoc_xmerl +format_timestamp .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^format_timestamp(TS) -> format_timestamp(TS, micro).$/;" f module:docsh_tracer +format_timestamp .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^format_timestamp({_, _, Micro} = TS, Precision) ->$/;" f module:docsh_tracer +format_usage_line .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^format_usage_line(MaxOptionLength, MaxLineLength, {OptionLength, OptionText, [_ | _] = HelpText})$/;" f module:getopt +format_usage_line .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^format_usage_line(_MaxOptionLength, MaxLineLength, {_OptionLength, OptionText, [_ | _] = HelpText}) ->$/;" f module:getopt +format_usage_line .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^format_usage_line(_MaxOptionLength, _MaxLineLength, {_OptionLength, OptionText, _HelpText}) ->$/;" f module:getopt +from_beam_file .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_beam.erl /^from_beam_file(BEAMFile) ->$/;" f module:docsh_beam +from_internal .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^from_internal(Internal) ->$/;" f module:docsh_docs_v1 +from_loaded_module .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_beam.erl /^from_loaded_module(Mod) ->$/;" f module:docsh_beam +function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^function({attribute, _, spec, _} = Spec) ->$/;" f module:docsh_syntax +function_arity .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^function_arity({attribute, _, spec, Data}) ->$/;" f module:docsh_syntax +function_name .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^function_name({attribute, _, spec, Data}) ->$/;" f module:docsh_syntax +function_signature .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^function_signature({attribute, _, spec, _} = Spec) ->$/;" f module:docsh_syntax +get .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^get(Key, Props) ->$/;" f module:docsh_lib +get .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^get(Key, Props, Default) ->$/;" f module:docsh_lib +get_abstract_code .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^get_abstract_code(BEAMFile) ->$/;" f module:docsh_lib +get_content .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_content(Name, Default, ContinueFun, #xmlElement{content = Content} = Element) ->$/;" f module:docsh_edoc_xmerl +get_description .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_description(#xmlElement{} = Element) ->$/;" f module:docsh_edoc_xmerl +get_docs .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^get_docs(M) ->$/;" f module:docsh_lib +get_env_var .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^get_env_var(Prefix, Suffix, []) ->$/;" f module:getopt +get_env_var .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^get_env_var(Prefix, Suffix, [_ | _] = Acc) ->$/;" f module:getopt +get_full_description .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_full_description(#xmlElement{name = description} = D) ->$/;" f module:docsh_edoc_xmerl +get_full_description .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_full_description(#xmlElement{name = fullDescription, content = XmlElementContent}) ->$/;" f module:docsh_edoc_xmerl +get_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_function(#xmlElement{attributes = Attrs} = Function) ->$/;" f module:docsh_edoc_xmerl +get_function_description .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_function_description(#xmlElement{name = function} = Function) ->$/;" f module:docsh_edoc_xmerl +get_functions .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_functions(#xmlElement{name = functions, content = Content}) ->$/;" f module:docsh_edoc_xmerl +get_functions .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_functions(#xmlElement{name = module} = M) ->$/;" f module:docsh_edoc_xmerl +get_functions .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^get_functions(Forms) ->$/;" f module:docsh_syntax +get_max_option_length .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^get_max_option_length({OptionText, HelpText}, PrevMaxOptionLength) ->$/;" f module:getopt +get_module_description .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_module_description(#xmlElement{name = module} = M) ->$/;" f module:docsh_edoc_xmerl +get_module_name .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_module_name(#xmlElement{attributes = Attrs}) ->$/;" f module:docsh_edoc_xmerl +get_module_name .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^get_module_name(Forms) ->$/;" f module:docsh_syntax +get_provider .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^get_provider(ProviderName, Providers) ->$/;" f module:providers +get_provider .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^get_provider(ProviderName, [_ | Rest], Namespace) ->$/;" f module:providers +get_provider .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^get_provider(ProviderName,$/;" f module:providers +get_provider .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^get_provider(_, _, _) ->$/;" f module:providers +get_provider .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^get_provider({Namespace, ProviderName}, Providers) ->$/;" f module:providers +get_provider_by_module .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^get_provider_by_module(ProviderModule, [Provider = #provider{module = ProviderModule} | _]) ->$/;" f module:providers +get_provider_by_module .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^get_provider_by_module(ProviderModule, [_ | Rest]) ->$/;" f module:providers +get_provider_by_module .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^get_provider_by_module(_ProviderModule, _) ->$/;" f module:providers +get_providers_by_namespace .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^get_providers_by_namespace(Namespace, [Provider = #provider{namespace = Namespace} | Rest]) ->$/;" f module:providers +get_providers_by_namespace .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^get_providers_by_namespace(Namespace, [_ | Rest]) ->$/;" f module:providers +get_providers_by_namespace .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^get_providers_by_namespace(_Namespace, []) ->$/;" f module:providers +get_readers .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^get_readers(Beam) ->$/;" f module:docsh_lib +get_source_file .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^get_source_file(BEAMFile) ->$/;" f module:docsh_lib +get_target_providers .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^get_target_providers(Target, Providers) ->$/;" f module:providers +get_target_providers .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^get_target_providers(Target, Providers, Namespace) ->$/;" f module:providers +get_target_providers .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^get_target_providers({Namespace, Target}, Providers) ->$/;" f module:providers +get_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_type(#xmlElement{name = typedecl} = Type) ->$/;" f module:docsh_edoc_xmerl +get_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^get_type(_) ->$/;" f module:docsh_syntax +get_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^get_type({attribute, _, T, _} = Type)$/;" f module:docsh_syntax +get_type_arity .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_type_arity(#xmlElement{name = argtypes, content = Content}) ->$/;" f module:docsh_edoc_xmerl +get_type_arity .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_type_arity(#xmlElement{name = typedecl} = Type) ->$/;" f module:docsh_edoc_xmerl +get_type_arity .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_type_arity(#xmlElement{name = typedef} = TypeDef) ->$/;" f module:docsh_edoc_xmerl +get_type_def .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_type_def(ContinueFun, #xmlElement{name = typedecl} = Type) ->$/;" f module:docsh_edoc_xmerl +get_type_description .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_type_description(#xmlElement{name = typedecl} = Type) ->$/;" f module:docsh_edoc_xmerl +get_type_name .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_type_name(#xmlElement{name = erlangName, attributes = Attrs}) ->$/;" f module:docsh_edoc_xmerl +get_type_name .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_type_name(#xmlElement{name = typedecl} = Type) ->$/;" f module:docsh_edoc_xmerl +get_type_name .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_type_name(#xmlElement{name = typedef} = TypeDef) ->$/;" f module:docsh_edoc_xmerl +get_types .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_types(#xmlElement{name = module} = M) ->$/;" f module:docsh_edoc_xmerl +get_types .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^get_types(#xmlElement{name = typedecls, content = Content}) ->$/;" f module:docsh_edoc_xmerl +get_types .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^get_types(Forms) ->$/;" f module:docsh_syntax +getopt .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^-module(getopt).$/;" m +group_by .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^group_by(F, L) ->$/;" f module:docsh_lib +guessed_source_file .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^guessed_source_file(BEAMFile) ->$/;" f module:docsh_lib +guessed_source_file .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^guessed_source_file(CompiledModule) when is_binary(CompiledModule) ->$/;" f module:docsh_lib +h .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/_build/shared/lib/docsh/include/docsh_user_default.hrl /^h(M, F) -> docsh_erl:h(M, F).$/;" f +h .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/_build/shared/lib/docsh/include/docsh_user_default.hrl /^h(M, F, A) -> docsh_erl:h(M, F, A).$/;" f +h .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/_build/shared/lib/docsh/include/docsh_user_default.hrl /^h(ModOrFun) -> docsh_erl:h(ModOrFun).$/;" f +h .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/include/docsh_user_default.hrl /^h(M, F) -> docsh_erl:h(M, F).$/;" f +h .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/include/docsh_user_default.hrl /^h(M, F, A) -> docsh_erl:h(M, F, A).$/;" f +h .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/include/docsh_user_default.hrl /^h(ModOrFun) -> docsh_erl:h(ModOrFun).$/;" f +h .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^h(Fun) when is_function(Fun) ->$/;" f module:docsh_erl +h .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^h(M) when is_atom(M) ->$/;" f module:docsh_erl +h .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^h(M, F) -> h(M, F, any).$/;" f module:docsh_erl +h .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^h(M, F, Arity) when is_atom(M), is_atom(F),$/;" f module:docsh_erl +handler .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^handler(Trace, Out) ->$/;" f module:docsh_tracer +handler .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^handler({trace, _Pid, call, _MFA} = Trace, Out) ->$/;" f module:docsh_tracer +handler .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^handler({trace, _Pid, return_from, _MFA, _Ret} = Trace, Out) ->$/;" f module:docsh_tracer +handler .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^handler({trace_ts, _Pid, call, _MFA, TS} = Trace, Out) ->$/;" f module:docsh_tracer +handler .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^handler({trace_ts, _Pid, return_from, _MFA, _Ret, TS} = Trace, Out) ->$/;" f module:docsh_tracer +has_docs .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^has_docs(BEAMFile) ->$/;" f module:docsh_lib +hello foo.py /^ def hello(self):$/;" m class:Mewto +help .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^help(#provider{opts=Opts$/;" f module:providers +help .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^help(Name, Providers) when is_atom(Name) ->$/;" f module:providers +help .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^help(Name, Providers) when is_list(Name) ->$/;" f module:providers +help .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^help(Name, Providers, Namespace) when is_atom(Name) ->$/;" f module:providers +help .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^help(Name, Providers, Namespace) when is_list(Name) ->$/;" f module:providers +help .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^help(Providers) when is_list(Providers) ->$/;" f module:providers +hooks .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^hooks(Provider) ->$/;" f module:providers +hooks .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^hooks(Provider, Hooks) ->$/;" f module:providers +i2b .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^-define(i2b(I), integer_to_binary(I)).$/;" d +i2b .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_internal.erl /^-define(i2b(I), integer_to_binary(I)).$/;" d +il2b .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^-define(il2b(IOList), iolist_to_binary(IOList)).$/;" d +il2b .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^-define(il2b(IOList), iolist_to_binary(IOList)).$/;" d +il2b .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl_flat.erl /^-define(il2b(IOList), iolist_to_binary(IOList)).$/;" d +il2b .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^-define(il2b(IOList), iolist_to_binary(IOList)).$/;" d +il2b .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_internal.erl /^-define(il2b(IOList), iolist_to_binary(IOList)).$/;" d +il2b .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^-define(il2b(IOList), iolist_to_binary(IOList)).$/;" d +il2b .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^-define(il2b, iolist_to_binary).$/;" d +il2l .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^-define(il2l(IOList), binary_to_list(iolist_to_binary(IOList))).$/;" d +impl .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^impl(Provider) ->$/;" f module:providers +init .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/rebar3_docsh.erl /^init(State) ->$/;" f module:rebar3_docsh +is_arg_false .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_arg_false(Arg) ->$/;" f module:getopt +is_arg_true .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_arg_true(Arg) ->$/;" f module:getopt +is_boolean_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_boolean_arg(Arg) ->$/;" f module:getopt +is_implicit_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_implicit_arg(_Type, _Arg) ->$/;" f module:getopt +is_implicit_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_implicit_arg(boolean, Arg) ->$/;" f module:getopt +is_implicit_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_implicit_arg(integer, Arg) ->$/;" f module:getopt +is_implicit_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_implicit_arg({Type, _DefaultArg}, Arg) ->$/;" f module:getopt +is_integer_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_integer_arg("-" ++ Tail) ->$/;" f module:getopt +is_integer_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_integer_arg(Arg) ->$/;" f module:getopt +is_module_available .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^is_module_available(Mod) ->$/;" f module:docsh_lib +is_non_neg_float_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_non_neg_float_arg([Head | Tail]) when (Head >= $0 andalso Head =< $9) orelse Head =:= $. ->$/;" f module:getopt +is_non_neg_float_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_non_neg_float_arg([]) ->$/;" f module:getopt +is_non_neg_float_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_non_neg_float_arg([_Head | _Tail]) ->$/;" f module:getopt +is_non_neg_integer_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_non_neg_integer_arg([Head | Tail]) when Head >= $0, Head =< $9 ->$/;" f module:getopt +is_non_neg_integer_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_non_neg_integer_arg([]) ->$/;" f module:getopt +is_non_neg_integer_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_non_neg_integer_arg([_Head | _Tail]) ->$/;" f module:getopt +is_preformatted .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^is_preformatted(Parents) ->$/;" f module:docsh_edoc_xmerl +is_valid_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_valid_arg(_Type, _Arg) ->$/;" f module:getopt +is_valid_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_valid_arg(boolean, Arg) ->$/;" f module:getopt +is_valid_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_valid_arg(float, Arg) ->$/;" f module:getopt +is_valid_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_valid_arg(integer, Arg) ->$/;" f module:getopt +is_valid_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^is_valid_arg({Type, _DefaultArg}, Arg) ->$/;" f module:getopt +item_doc_hidden .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_format.erl /^item_doc_hidden() ->$/;" f module:docsh_format +item_doc_not_available .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_format.erl /^item_doc_not_available() ->$/;" f module:docsh_format +iterate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers_topo.erl /^iterate(Pairs, L, All) ->$/;" f module:providers_topo +iterate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers_topo.erl /^iterate([], L, All) ->$/;" f module:providers_topo +key_to_module .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^key_to_module(M) when is_atom(M) -> M;$/;" f module:docsh_erl +key_to_module .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^key_to_module({M,_,_}) -> M.$/;" f module:docsh_erl +kna .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_internal.erl /^kna(#{kind := K, name := N, arity := A}) -> {K, N, A}.$/;" f module:docsh_internal +kna_signature .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^kna_signature(ModuleInfo, Info) ->$/;" f module:docsh_docs_v1 +l .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^-define(l(Args), fun () -> Args end).$/;" d +l .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^-define(l(Args), fun () -> Args end).$/;" d +l2b .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl_flat.erl /^-define(l2b(L), list_to_binary(L)).$/;" d +l2ea .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^-define(l2ea(L), list_to_existing_atom(L)).$/;" d +l2ea .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl_flat.erl /^-define(l2ea(L), list_to_existing_atom(L)).$/;" d +l2i .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^-define(l2i(L), list_to_integer(L)).$/;" d +l2i .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl_flat.erl /^-define(l2i(L), list_to_integer(L)).$/;" d +lexemes .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^lexemes(Str, Separators) -> string:lexemes(Str, Separators).$/;" f module:getopt +lexemes .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^lexemes(Str, Separators) -> string:tokens(Str, Separators).$/;" f module:getopt +lexer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^-module(lexer).$/;" m +lhs .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers_topo.erl /^lhs(L) ->$/;" f module:providers_topo +line_length .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^line_length() ->$/;" f module:getopt +list_to_boolean .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^list_to_boolean("no") -> false.$/;" f module:docsh_edoc_xmerl +list_to_boolean .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^list_to_boolean("yes") -> true;$/;" f module:docsh_edoc_xmerl +load_shell_extensions .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^load_shell_extensions() ->$/;" f module:docsh +lookup .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^lookup(#docs_v1{} = Docs, Key, Kinds0) ->$/;" f module:docsh_docs_v1 +lookup .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^lookup(Key, Kinds) ->$/;" f module:docsh_erl +lookup .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_format.erl /^lookup(Docs, Key, Items) ->$/;" f module:docsh_format +lowercase .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^lowercase(Str) -> string:lowercase(Str).$/;" f module:getopt +lowercase .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^lowercase(Str) -> string:to_lower(Str).$/;" f module:getopt +main .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^main(Args) ->$/;" f module:docsh +make_docs .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^make_docs(Beam) ->$/;" f module:docsh_lib +make_docs_chunk .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/rebar3_docsh.erl /^make_docs_chunk(Docs) ->$/;" f module:rebar3_docsh +merge .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_internal.erl /^merge([Info1, Info2 | Rest]) ->$/;" f module:docsh_internal +merge .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_internal.erl /^merge([Info]) -> Info;$/;" f module:docsh_internal +merge .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_internal.erl /^merge([]) -> [];$/;" f module:docsh_internal +merge_two .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_internal.erl /^merge_two(#{items := Items1} = Info1, #{items := Items2}) ->$/;" f module:docsh_internal +merge_two_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_internal.erl /^merge_two_({{Kind, Name, Arity}, [Item1, Item2]}) ->$/;" f module:docsh_internal +merge_two_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_internal.erl /^merge_two_({{Kind, Name, Arity}, [Item]}) ->$/;" f module:docsh_internal +mk_select .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^mk_select(Kind, Name, Arity) ->$/;" f module:docsh_docs_v1 +mk_step .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^mk_step(ModuleInfo) ->$/;" f module:docsh_docs_v1 +module .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_internal.erl /^module(#{name := Name}) -> Name.$/;" f module:docsh_internal +module .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^module(Provider) ->$/;" f module:providers +module_doc .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^module_doc( Lang, D) -> #{Lang => D}.$/;" f module:docsh_docs_v1 +module_doc .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^module_doc(_Lang, none) -> none;$/;" f module:docsh_docs_v1 +module_doc_hidden .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_format.erl /^module_doc_hidden() ->$/;" f module:docsh_format +module_doc_not_available .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_format.erl /^module_doc_not_available() ->$/;" f module:docsh_format +name .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_beam.erl /^name(B) -> B#docsh_beam.name.$/;" f module:docsh_beam +namespace .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^namespace(Provider) ->$/;" f module:providers +namespace_help .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^namespace_help(Dict, [NS|Namespaces]) ->$/;" f module:providers +namespace_help .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^namespace_help(_, []) -> ok;$/;" f module:providers +new .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^new(ModuleName, State) when is_atom(ModuleName) ->$/;" f module:providers +not_ebin .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^not_ebin("ebin") -> false;$/;" f module:docsh_lib +not_ebin .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^not_ebin(_) -> true.$/;" f module:docsh_lib +not_src .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^not_src("src") -> false;$/;" f module:docsh_lib +not_src .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^not_src(_) -> true.$/;" f module:docsh_lib +opts .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^opts(Provider) ->$/;" f module:providers +padding .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^padding(1) -> "";$/;" f module:docsh +padding .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^padding(_) -> " ".$/;" f module:docsh +parse .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^parse(Tokens) ->$/;" f module:parser +parse .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^parse(OptSpecList, CmdLine) when is_list(CmdLine) ->$/;" f module:getopt +parse .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^parse(OptSpecList, OptAcc, ArgAcc, ArgPos, ["-" ++ ([_Char | _] = OptArg) = OptStr | Tail]) ->$/;" f module:getopt +parse .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^parse(OptSpecList, OptAcc, ArgAcc, ArgPos, ["--" ++ OptArg = OptStr | Tail]) ->$/;" f module:getopt +parse .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^parse(OptSpecList, OptAcc, ArgAcc, ArgPos, [Arg | Tail]) ->$/;" f module:getopt +parse .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^parse(OptSpecList, OptAcc, ArgAcc, _ArgPos, ["--" | Tail]) ->$/;" f module:getopt +parse .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^parse(OptSpecList, OptAcc, ArgAcc, _ArgPos, []) ->$/;" f module:getopt +parse_and_check .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^parse_and_check(OptSpecList, CmdLine) when is_list(OptSpecList), is_list(CmdLine) ->$/;" f module:getopt +parse_and_scan .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^parse_and_scan({F, A}) ->$/;" f module:parser +parse_and_scan .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^parse_and_scan({M, F, A}) ->$/;" f module:parser +parse_long_option .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^parse_long_option(OptSpecList, OptAcc, ArgAcc, ArgPos, Args, OptStr, OptArg) ->$/;" f module:getopt +parse_long_option_assigned_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^parse_long_option_assigned_arg(OptSpecList, OptAcc, ArgAcc, ArgPos, Args, OptStr, Long, Arg) ->$/;" f module:getopt +parse_long_option_next_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^parse_long_option_next_arg(OptSpecList, OptAcc, ArgAcc, ArgPos, Args, {Name, _Short, _Long, ArgSpec, _Help} = OptSpec) ->$/;" f module:getopt +parse_short_option .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^parse_short_option(OptSpecList, OptAcc, ArgAcc, ArgPos, Args, OptStr, OptArg) ->$/;" f module:getopt +parse_short_option .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^parse_short_option(OptSpecList, OptAcc, ArgAcc, ArgPos, Args, OptStr, OptPos, [Short | Arg]) ->$/;" f module:getopt +parse_short_option .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^parse_short_option(OptSpecList, OptAcc, ArgAcc, ArgPos, Args, _OptStr, _OptPos, []) ->$/;" f module:getopt +parse_short_option_next_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^parse_short_option_next_arg(OptSpecList, OptAcc, ArgAcc, ArgPos, Args, {Name, _Short, _Long, ArgSpec, _Help} = OptSpec, OptPos) ->$/;" f module:getopt +parser .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^-module(parser).$/;" m +pass_to_dbg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^pass_to_dbg(Trace, Out) ->$/;" f module:docsh_tracer +poke foo.py /^def poke(a, b):$/;" f +pp .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^pp(Content) ->$/;" f module:docsh_edoc +prepend .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^prepend( Prefix, [Node | Doc], Acc) -> prepend(Prefix, Doc, [Node | Acc]).$/;" f module:docsh_edoc_xmerl +prepend .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^prepend( Prefix, [{br} | Doc], Acc) -> prepend(Prefix, Doc, [{br}, {i, Prefix} | Acc]);$/;" f module:docsh_edoc_xmerl +prepend .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^prepend( Prefix, [{br} | Doc], [] = Acc) -> prepend(Prefix, Doc, [{br} | Acc]);$/;" f module:docsh_edoc_xmerl +prepend .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^prepend( Prefix, [{br} | Doc], [{br}, {br}] = Acc) -> prepend(Prefix, Doc, Acc);$/;" f module:docsh_edoc_xmerl +prepend .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^prepend( Prefix, [{br} | Doc], [{br}] = Acc) -> prepend(Prefix, Doc, [{br} | Acc]);$/;" f module:docsh_edoc_xmerl +prepend .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^prepend(Prefix, Doc) -> prepend(Prefix, lists:reverse(Doc), []).$/;" f module:docsh_edoc_xmerl +prepend .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^prepend(_Prefix, [], Acc) -> Acc;$/;" f module:docsh_edoc_xmerl +print .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^print(Fmt, Args) ->$/;" f module:docsh_lib +print .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^print(Handle, Fmt, Args) ->$/;" f module:docsh_lib +print .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^print(Handle, Fmt, Args) ->$/;" f module:docsh_tracer +print_warnings .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/rebar3_docsh.erl /^print_warnings(Name, Warnings) ->$/;" f module:rebar3_docsh +process_app .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/rebar3_docsh.erl /^process_app(State, App) ->$/;" f module:rebar3_docsh +process_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^process_arg({_Desc, F}, {next, Args}) ->$/;" f module:docsh +process_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^process_arg({_Desc, _}, done) -> done;$/;" f module:docsh +process_args .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^process_args(Args, Opts) ->$/;" f module:docsh +process_beam .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/rebar3_docsh.erl /^process_beam(_State, BeamFile) ->$/;" f module:rebar3_docsh +process_dep .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^process_dep({Namespace, ProviderName}, {Deps, Providers, Seen}) ->$/;" f module:providers +process_deps .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^process_deps(Provider, Providers, Seen) ->$/;" f module:providers +process_deps .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^process_deps(TargetProviders, Providers) ->$/;" f module:providers +process_deps .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^process_deps([], _Providers) ->$/;" f module:providers +profiles .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^profiles(Provider) ->$/;" f module:providers +progname .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^progname() ->$/;" f module:docsh +provider .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/provider.erl /^-module(provider).$/;" m +provider .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^-record(provider, { name :: atom(), % The 'user friendly' name of the task$/;" r +providers .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^-module(providers).$/;" m +providers_topo .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers_topo.erl /^-module(providers_topo).$/;" m +raw_abstract_v1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^raw_abstract_v1({raw_abstract_v1, Forms}) ->$/;" f module:docsh_lib +readlink_f .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/_build/shared/lib/elixir_ls_utils/priv/debugger.sh /^readlink_f () {$/;" f +readlink_f .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/_build/shared/lib/elixir_ls_utils/priv/language_server.sh /^readlink_f () {$/;" f +readlink_f .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/_build/shared/lib/elixir_ls_utils/priv/launch.sh /^readlink_f () {$/;" f +readlink_f .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/apps/elixir_ls_utils/priv/debugger.sh /^readlink_f () {$/;" f +readlink_f .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/apps/elixir_ls_utils/priv/language_server.sh /^readlink_f () {$/;" f +readlink_f .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/apps/elixir_ls_utils/priv/launch.sh /^readlink_f () {$/;" f +rebar3_docsh .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/rebar3_docsh.erl /^-module(rebar3_docsh).$/;" m +remove_duplicates .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers_topo.erl /^remove_duplicates([H|T]) ->$/;" f module:providers_topo +remove_duplicates .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers_topo.erl /^remove_duplicates([]) ->$/;" f module:providers_topo +remove_pairs .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers_topo.erl /^remove_pairs(L1, L2) ->$/;" f module:providers_topo +reorder_providers .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers.erl /^reorder_providers(OProviderList) ->$/;" f module:providers +return_error .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^return_error(Location, Message) ->$/;" f module:parser +rhs .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers_topo.erl /^rhs(L) ->$/;" f module:providers_topo +s .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/_build/shared/lib/docsh/include/docsh_user_default.hrl /^s(Fun) -> docsh_erl:s(Fun).$/;" f +s .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/_build/shared/lib/docsh/include/docsh_user_default.hrl /^s(M, F) -> docsh_erl:s(M, F).$/;" f +s .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/_build/shared/lib/docsh/include/docsh_user_default.hrl /^s(M, F, A) -> docsh_erl:s(M, F, A).$/;" f +s .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/include/docsh_user_default.hrl /^s(Fun) -> docsh_erl:s(Fun).$/;" f +s .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/include/docsh_user_default.hrl /^s(M, F) -> docsh_erl:s(M, F).$/;" f +s .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/include/docsh_user_default.hrl /^s(M, F, A) -> docsh_erl:s(M, F, A).$/;" f +s .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^s(Fun) when is_function(Fun) ->$/;" f module:docsh_erl +s .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^s(M, F) -> s(M, F, any).$/;" f module:docsh_erl +s .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^s(M, F, Arity) when is_atom(M), is_atom(F),$/;" f module:docsh_erl +select .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^select(Kind, Name, Arity, {Kind, ItemName, ItemArity})$/;" f module:docsh_docs_v1 +select .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^select(_, _, _, _) ->$/;" f module:docsh_docs_v1 +sidebarNodes.extras .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/mix_task_archive_deps/doc/dist/sidebar_items-7b4a3e61e6.js /^sidebarNodes={"extras":[{"id":"api-reference","title":"API Reference","group":"","headers":[{"id":"Modules","anchor":"modules"},{"id":"Command line options","anchor":"command-line-options"}]}],"exceptions":[],"modules":[{"id":"Mix.Archive.Build.Helpers","title":"Mix.Archive.Build.Helpers","functions":[{"id":"destination\/1","anchor":"destination\/1"},{"id":"skipped_apps\/1","anchor":"skipped_apps\/1"}]},{"id":"Mix.Tasks.Archive.Build.All","title":"Mix.Tasks.Archive.Build.All","functions":[{"id":"run\/1","anchor":"run\/1"}]},{"id":"Mix.Tasks.Archive.Build.All.List","title":"Mix.Tasks.Archive.Build.All.List","functions":[{"id":"run\/1","anchor":"run\/1"}]},{"id":"Mix.Tasks.Archive.Build.Deps","title":"Mix.Tasks.Archive.Build.Deps","functions":[{"id":"build_archives\/1","anchor":"build_archives\/1"},{"id":"list_archives\/1","anchor":"list_archives\/1"},{"id":"run\/1","anchor":"run\/1"}]},{"id":"Mix.Tasks.Archive.Build.Elixir","title":"Mix.Tasks.Archive.Build.Elixir","functions":[{"id":"build_archives\/1","anchor":"build_archives\/1"},{"id":"list_archives\/1","anchor":"list_archives\/1"},{"id":"run\/1","anchor":"run\/1"}]}],"protocols":[]}/;" p +signature .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^signature(ModuleInfo, Info) ->$/;" f module:docsh_docs_v1 +skip_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^skip_cont(Rest, Line, skip_token, Error) ->$/;" f module:lexer +skip_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^skip_cont(Rest, Line, {end_token,_T,Push}, Error) ->$/;" f module:lexer +skip_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^skip_cont(Rest, Line, {end_token,_T}, Error) ->$/;" f module:lexer +skip_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^skip_cont(Rest, Line, {error,_S}, Error) ->$/;" f module:lexer +skip_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^skip_cont(Rest, Line, {skip_token,Push}, Error) ->$/;" f module:lexer +skip_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^skip_cont(Rest, Line, {token,_T,Push}, Error) ->$/;" f module:lexer +skip_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^skip_cont(Rest, Line, {token,_T}, Error) ->$/;" f module:lexer +skip_tokens .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^skip_tokens(Ics, Line, Error) ->$/;" f module:lexer +skip_tokens .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^skip_tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Error, A0, Alen0) ->$/;" f module:lexer +sort .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers_topo.erl /^sort(Pairs) ->$/;" f module:providers_topo +source_file .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_beam.erl /^source_file(B) -> B#docsh_beam.source_file.$/;" f module:docsh_beam +source_file .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_beam.erl /^source_file(B, NewFile) -> B#docsh_beam{source_file = NewFile}.$/;" f module:docsh_beam +split .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc_xmerl.erl /^split(Text, Pattern, Opts) ->$/;" f module:docsh_edoc_xmerl +split_assigned_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^split_assigned_arg(OptStr) ->$/;" f module:getopt +split_assigned_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^split_assigned_arg(OptStr, [Char | Tail], Acc) ->$/;" f module:getopt +split_assigned_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^split_assigned_arg(OptStr, [], _Acc) ->$/;" f module:getopt +split_assigned_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^split_assigned_arg(_OptStr, "=" ++ Tail, Acc) ->$/;" f module:getopt +src_suffix .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^src_suffix(BEAMFile) ->$/;" f module:docsh_lib +start .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^start() ->$/;" f module:docsh_tracer +step .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_docs_v1.erl /^step(ModuleInfo, Info, { #docs_v1{} = DocsV1, DocsMap }) ->$/;" f module:docsh_docs_v1 +stick_module .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^stick_module(Module) -> stick_module(Module, code:is_sticky(Module)).$/;" f module:docsh_lib +stick_module .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^stick_module(Module, false) -> code:stick_mod(Module);$/;" f module:docsh_lib +stick_module .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^stick_module(_,_) -> false.$/;" f module:docsh_lib +string .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^string(Ics0, L0, Tcs, Ts) ->$/;" f module:lexer +string .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^string(String) -> string(String, 1).$/;" f module:lexer +string .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^string(String, Line) -> string(String, Line, String, []).$/;" f module:lexer +string .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^string([], L, [], Ts) -> % No partial tokens!$/;" f module:lexer +string_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^string_cont(Rest, Line, skip_token, Ts) ->$/;" f module:lexer +string_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^string_cont(Rest, Line, {end_token,T,Push}, Ts) ->$/;" f module:lexer +string_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^string_cont(Rest, Line, {end_token,T}, Ts) ->$/;" f module:lexer +string_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^string_cont(Rest, Line, {skip_token,Push}, Ts) ->$/;" f module:lexer +string_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^string_cont(Rest, Line, {token,T,Push}, Ts) ->$/;" f module:lexer +string_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^string_cont(Rest, Line, {token,T}, Ts) ->$/;" f module:lexer +string_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^string_cont(_Rest, Line, {error,S}, _Ts) ->$/;" f module:lexer +strip_ts .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^strip_ts({trace_ts, Pid, call, MFA, _TS}) -> {trace, Pid, call, MFA};$/;" f module:docsh_tracer +strip_ts .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^strip_ts({trace_ts, Pid, return_from, MFA, Ret, _TS}) -> {trace, Pid, return_from, MFA, Ret}.$/;" f module:docsh_tracer +subtract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/providers/src/providers_topo.erl /^subtract(L1, L2) ->$/;" f module:providers_topo +t .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/_build/shared/lib/docsh/include/docsh_user_default.hrl /^t(M) -> docsh_erl:t(M).$/;" f +t .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/_build/shared/lib/docsh/include/docsh_user_default.hrl /^t(M, T) -> docsh_erl:t(M, T).$/;" f +t .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/_build/shared/lib/docsh/include/docsh_user_default.hrl /^t(M, T, A) -> docsh_erl:t(M, T, A).$/;" f +t .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/include/docsh_user_default.hrl /^t(M) -> docsh_erl:t(M).$/;" f +t .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/include/docsh_user_default.hrl /^t(M, T) -> docsh_erl:t(M, T).$/;" f +t .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/include/docsh_user_default.hrl /^t(M, T, A) -> docsh_erl:t(M, T, A).$/;" f +t .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^t(M) when is_atom(M) ->$/;" f module:docsh_erl +t .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^t(M, T) -> t(M, T, any).$/;" f module:docsh_erl +t .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_erl.erl /^t(M, T, Arity) when is_atom(M), is_atom(T),$/;" f module:docsh_erl +to_internal .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^to_internal(Beam) ->$/;" f module:docsh_edoc +to_internal .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^to_internal(Beam, Opts) ->$/;" f module:docsh_edoc +to_internal .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^to_internal(Beam) ->$/;" f module:docsh_syntax +to_string .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^to_string(Atom) when is_atom(Atom) ->$/;" f module:getopt +to_string .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^to_string(List) when is_list(List) ->$/;" f module:getopt +to_string .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^to_string(Value) ->$/;" f module:getopt +to_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^to_type(_Type, Arg) ->$/;" f module:getopt +to_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^to_type(atom, Arg) ->$/;" f module:getopt +to_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^to_type(binary, Arg) ->$/;" f module:getopt +to_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^to_type(boolean, Arg) ->$/;" f module:getopt +to_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^to_type(float, Arg) ->$/;" f module:getopt +to_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^to_type(integer, Arg) ->$/;" f module:getopt +to_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^to_type({Type, _DefaultArg}, Arg) ->$/;" f module:getopt +token .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^token(Cont, Chars) -> token(Cont, Chars, 1).$/;" f module:lexer +token .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^token(S0, Ics0, L0, Tcs, Tlen0, Tline, A0, Alen0) ->$/;" f module:lexer +token .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^token([], Chars, Line) ->$/;" f module:lexer +token .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^token({token,State,Line,Tcs,Tlen,Tline,Action,Alen}, Chars, _) ->$/;" f module:lexer +token_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^token_cont(Rest, Line, skip_token) ->$/;" f module:lexer +token_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^token_cont(Rest, Line, {end_token,T,Push}) ->$/;" f module:lexer +token_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^token_cont(Rest, Line, {end_token,T}) ->$/;" f module:lexer +token_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^token_cont(Rest, Line, {error,S}) ->$/;" f module:lexer +token_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^token_cont(Rest, Line, {skip_token,Push}) ->$/;" f module:lexer +token_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^token_cont(Rest, Line, {token,T,Push}) ->$/;" f module:lexer +token_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^token_cont(Rest, Line, {token,T}) ->$/;" f module:lexer +tokenize .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^tokenize(CmdLine) ->$/;" f module:getopt +tokenize .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^tokenize([$\\\\, Char | Tail], Acc, ArgAcc) ->$/;" f module:getopt +tokenize .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^tokenize([Char | Tail], Acc, ArgAcc) ->$/;" f module:getopt +tokenize .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^tokenize([Char | _Tail] = CmdLine, Acc, ArgAcc) when Char =:= $$; Char =:= $% ->$/;" f module:getopt +tokenize .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^tokenize([QuotationMark | Tail], Acc, ArgAcc) when QuotationMark =:= $"; QuotationMark =:= $' ->$/;" f module:getopt +tokenize .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^tokenize([Sep | Tail], Acc, ArgAcc) when ?IS_WHITESPACE(Sep) ->$/;" f module:getopt +tokenize .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^tokenize([], Acc, ArgAcc) ->$/;" f module:getopt +tokenize .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^tokenize([], Acc, []) ->$/;" f module:getopt +tokenize_quoted_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^tokenize_quoted_arg($" = QuotationMark, [Char | _Tail] = CmdLine, Acc, ArgAcc) when Char =:= $$; Char =:= $% ->$/;" f module:getopt +tokenize_quoted_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^tokenize_quoted_arg(QuotationMark, [$\\\\, Char | Tail], Acc, ArgAcc) ->$/;" f module:getopt +tokenize_quoted_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^tokenize_quoted_arg(QuotationMark, [Char | Tail], Acc, ArgAcc) ->$/;" f module:getopt +tokenize_quoted_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^tokenize_quoted_arg(QuotationMark, [QuotationMark | Tail], Acc, ArgAcc) ->$/;" f module:getopt +tokenize_quoted_arg .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^tokenize_quoted_arg(_QuotationMark, CmdLine, Acc, ArgAcc) ->$/;" f module:getopt +tokens .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^tokens(Cont, Chars) -> tokens(Cont, Chars, 1).$/;" f module:lexer +tokens .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Ts, A0, Alen0) ->$/;" f module:lexer +tokens .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^tokens([], Chars, Line) ->$/;" f module:lexer +tokens .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^tokens({skip_tokens,State,Line,Tcs,Tlen,Tline,Error,Action,Alen}, Chars, _) ->$/;" f module:lexer +tokens .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^tokens({tokens,State,Line,Tcs,Tlen,Tline,Ts,Action,Alen}, Chars, _) ->$/;" f module:lexer +tokens_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^tokens_cont(Rest, Line, skip_token, Ts) ->$/;" f module:lexer +tokens_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^tokens_cont(Rest, Line, {end_token,T,Push}, Ts) ->$/;" f module:lexer +tokens_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^tokens_cont(Rest, Line, {end_token,T}, Ts) ->$/;" f module:lexer +tokens_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^tokens_cont(Rest, Line, {error,S}, _Ts) ->$/;" f module:lexer +tokens_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^tokens_cont(Rest, Line, {skip_token,Push}, Ts) ->$/;" f module:lexer +tokens_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^tokens_cont(Rest, Line, {token,T,Push}, Ts) ->$/;" f module:lexer +tokens_cont .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^tokens_cont(Rest, Line, {token,T}, Ts) ->$/;" f module:lexer +tracer_monitor .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^tracer_monitor(Pid) ->$/;" f module:docsh_tracer +translate_args .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^translate_args({trace, Pid, call, {M, F, Args}}) ->$/;" f module:docsh_tracer +translate_one .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^translate_one(Val) ->$/;" f module:docsh_tracer +translate_ret .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^translate_ret({trace, Pid, return_from, MFA, Ret}) ->$/;" f module:docsh_tracer +translations .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_tracer.erl /^translations() ->$/;" f module:docsh_tracer +type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^type({attribute, _, T, _} = Type)$/;" f module:docsh_syntax +type_arity .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^type_arity({attribute, _, T, Data})$/;" f module:docsh_syntax +type_name .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^type_name({attribute, _, T, Data})$/;" f module:docsh_syntax +type_signature .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_syntax.erl /^type_signature({attribute, _, T, _} = Type)$/;" f module:docsh_syntax +unstick_module .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^unstick_module(Module) -> unstick_module(Module, code:is_sticky(Module)).$/;" f module:docsh_lib +unstick_module .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^unstick_module(Module, true) -> code:unstick_mod(Module);$/;" f module:docsh_lib +unstick_module .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_lib.erl /^unstick_module(_,_) -> false.$/;" f module:docsh_lib +unwrap .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^unwrap({_,_,V}) -> V.$/;" f module:parser +usage .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^usage() ->$/;" f module:docsh +usage .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^usage(_) ->$/;" f module:docsh +usage .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage(OptSpecList, ProgramName) ->$/;" f module:getopt +usage .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage(OptSpecList, ProgramName, CmdLineTail) ->$/;" f module:getopt +usage .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage(OptSpecList, ProgramName, CmdLineTail, Description, OptionsTail, OutputStream) ->$/;" f module:getopt +usage .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage(OptSpecList, ProgramName, CmdLineTail, OptionsTail) ->$/;" f module:getopt +usage .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage(OptSpecList, ProgramName, CmdLineTail, OptionsTail, OutputStream) ->$/;" f module:getopt +usage .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage(OptSpecList, ProgramName, CmdLineTail, OutputStream) when is_atom(OutputStream) ->$/;" f module:getopt +usage .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage(OptSpecList, ProgramName, OutputStream) when is_atom(OutputStream) ->$/;" f module:getopt +usage_cmd_line .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_cmd_line(ProgramName, OptSpecList) ->$/;" f module:getopt +usage_cmd_line .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_cmd_line(ProgramName, OptSpecList, CmdLineTail) ->$/;" f module:getopt +usage_cmd_line_option .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_cmd_line_option(Option) when is_list(Option) ->$/;" f module:getopt +usage_cmd_line_option .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_cmd_line_option({Name, Short, Long, ArgSpec, _Help}) when is_atom(ArgSpec) ->$/;" f module:getopt +usage_cmd_line_option .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_cmd_line_option({Name, Short, Long, ArgSpec, _Help}) when is_tuple(ArgSpec) ->$/;" f module:getopt +usage_cmd_line_option .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_cmd_line_option({_Name, Short, _Long, undefined, _Help}) when Short =\/= undefined ->$/;" f module:getopt +usage_cmd_line_option .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_cmd_line_option({_Name, _Short, Long, undefined, _Help}) when Long =\/= undefined ->$/;" f module:getopt +usage_cmd_line_option .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_cmd_line_option({_Name, _Short, _Long, undefined, _Help}) ->$/;" f module:getopt +usage_cmd_line_options .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_cmd_line_options(MaxLineLength, OptSpecList, CmdLineTail) ->$/;" f module:getopt +usage_cmd_line_options .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_cmd_line_options(MaxLineLength, [OptSpec | Tail], LineAcc, LineAccLength, Acc) ->$/;" f module:getopt +usage_cmd_line_options .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_cmd_line_options(MaxLineLength, [], [_ | _] = LineAcc, _LineAccLength, Acc) ->$/;" f module:getopt +usage_cmd_line_options .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_cmd_line_options(_MaxLineLength, [], [], _LineAccLength, Acc) ->$/;" f module:getopt +usage_help_text .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_help_text({_Name, _Short, _Long, _ArgSpec, Help}) ->$/;" f module:getopt +usage_help_text .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_help_text({_Name, _Short, _Long, {_ArgType, ArgValue}, [_ | _] = Help}) ->$/;" f module:getopt +usage_option_text .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_option_text({Name, undefined, undefined, _ArgSpec, _Help}) ->$/;" f module:getopt +usage_option_text .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_option_text({_Name, Short, Long, _ArgSpec, _Help}) ->$/;" f module:getopt +usage_option_text .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_option_text({_Name, Short, undefined, _ArgSpec, _Help}) ->$/;" f module:getopt +usage_option_text .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_option_text({_Name, undefined, Long, _ArgSpec, _Help}) ->$/;" f module:getopt +usage_options .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_options(OptSpecList) ->$/;" f module:getopt +usage_options .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^usage_options(OptSpecList, CustomHelp) ->$/;" f module:getopt +version .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh.erl /^version() ->$/;" f module:docsh +wrap_text_line .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^wrap_text_line(Length, Text) ->$/;" f module:getopt +wrap_text_line .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^wrap_text_line(Length, [Char | Tail], Acc, Count, CurrentLineAcc) when Count < Length ->$/;" f module:getopt +wrap_text_line .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^wrap_text_line(Length, [_ | _] = Help, Acc, Count, CurrentLineAcc) ->$/;" f module:getopt +wrap_text_line .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^wrap_text_line(_Length, [], Acc, _Count, [_ | _] = CurrentLineAcc) ->$/;" f module:getopt +wrap_text_line .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/getopt/src/getopt.erl /^wrap_text_line(_Length, [], Acc, _Count, _CurrentLineAcc) ->$/;" f module:getopt +write .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^write(Mod, Tag, OutDir, Content) ->$/;" f module:docsh_edoc +write .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/docsh/src/docsh_edoc.erl /^write(Mod, Tag, print, Content) ->$/;" f module:docsh_edoc +yecc_end .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecc_end(Location) ->$/;" f module:parser +yecc_error_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecc_error_type(function_clause, [{?MODULE,F,ArityOrArgs,_} | _]) ->$/;" f module:parser +yeccerror .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccerror(Token) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(115=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(118=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(119=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(124=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(21=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(23=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(24=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(2=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(30=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(34=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(35=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(36=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(48=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(52=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(58=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(67=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_assignment .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_assignment(83=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(0, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(100, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(102, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(104, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(105, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(106, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(107, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(115, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(118, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(119, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(123, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(124, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(127, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(17, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(2, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(20, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(21, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(23, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(24, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(30, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(34, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(35, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(36, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(48, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(50, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(52, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(58, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(64, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(67, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(83, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_atom .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_atom(99, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(115=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(118=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(119=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(124=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(21=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(23=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(24=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(2=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(30=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(34=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(35=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(36=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(48=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(52=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(58=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(67=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary(83=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary_items .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary_items(58, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary_items .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary_items(72=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary_part .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary_part(58, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_binary_part .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_binary_part(72, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte(110, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte(83, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_items .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_items(110=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_items .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_items(83, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(115=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(118=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(119=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(124=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(21=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(23=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(24=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(2=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(30=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(34=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(35=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(36=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(48=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(52=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(58=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(67=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_byte_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_byte_list(83=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(115=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(118=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(119=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(124=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(21=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(23=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(24=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(28, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(2=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(30=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(34=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(35=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(36=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(48=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(52=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(58=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(67=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_contract .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_contract(83=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_document .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_document(0, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(0, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(115, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(118, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(119, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(124, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(2, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(20, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(21, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(23, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(24, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(28, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(30, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(34, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(35, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(36, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(48, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(50, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(52, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(58, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(64, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(67, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_function .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_function(83, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(0, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(100=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(102=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(105=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(115, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(118, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(119, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(124, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(128=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(17=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(2, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(20, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(21, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(23, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(24, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(30, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(34, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(35, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(36, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(48, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(50, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(52, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(58, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(64, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(67, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_integer .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_integer(83, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(0, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(115, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(118, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(119, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(124, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(17=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(2, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(20, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(21, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(23, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(24, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(28, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(30, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(34, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(35, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(36, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(48, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(50, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(52, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(58, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(64, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(67, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_list(83, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(115=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(118=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(119=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(124=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(21=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(23=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(24=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(2=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(30=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(34=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(35=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(36=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(48=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(52=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(58=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(67=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map(83=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map_entry .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map_entry(115, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map_entry .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map_entry(83, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map_items .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map_items(115=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_map_items .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_map_items(83, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(115=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(118=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(119=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(124=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(21=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(23=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(24=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(2=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(30=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(34=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(35=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(36=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(48=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(52=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(58=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(67=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pattern .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pattern(83=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(115=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(118=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(119=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(124=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(21=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(23=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(24=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(2=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(30=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(34=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(35=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(36=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(48=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(52=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(58=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(67=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_pipe_list .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_pipe_list(83=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(115=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(118=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(119=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(124=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(21=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(23=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(24=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(2=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(30=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(34=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(35=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(36=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(48=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(52=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(58=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(67=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_range .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_range(83=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(115=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(118=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(119=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(124=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(21=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(23=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(24=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(2=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(30=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(34=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(35=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(36=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(48=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(52=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(58=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(67=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_rest .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_rest(83=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(115=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(118=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(119=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(124=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(21=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(23=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(24=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(2=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(30=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(34=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(35=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(36=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(48=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(52=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(58=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(67=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_tuple .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_tuple(83=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(115=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(118=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(119=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(123=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(124=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(21=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(23=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(24=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(2=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(30=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(34=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(35=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(36=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(48=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(52=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(58=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(67=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_type .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_type(83=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(0, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(115, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(118, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(119, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(124, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(2, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(20, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(21, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(23, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(24, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(30, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(34, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(35, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(36, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(48, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(50, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(52, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(58, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(64, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(67, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value(83, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value_items .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value_items(21, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value_items .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value_items(23, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value_items .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value_items(24, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value_items .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value_items(30, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value_items .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value_items(34=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value_items .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value_items(52=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_value_items .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_value_items(58, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_values .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_values(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccgoto_values .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccgoto_values(2=_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars0(Tokens, Tzr, State, States, Vstack) ->$/;" f module:parser +yeccpars1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars1(State1, State, States, Vstack, Token0, [Token | Tokens], Tzr) ->$/;" f module:parser +yeccpars1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, Location}) ->$/;" f module:parser +yeccpars1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, no_location}) ->$/;" f module:parser +yeccpars1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars1(State1, State, States, Vstack, Token0, [], {{_F,_A}, _Location}=Tzr) ->$/;" f module:parser +yeccpars1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars1([Token | Tokens], Tzr, State, States, Vstack) ->$/;" f module:parser +yeccpars1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars1([], {no_func, EndLocation}, State, States, Vstack) ->$/;" f module:parser +yeccpars1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars1([], {no_func, no_location}, State, States, Vstack) ->$/;" f module:parser +yeccpars1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars1([], {{F, A},_Location}, State, States, Vstack) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(103=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(104=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(106=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(108=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(109=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(110=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(112=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(113=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(114=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(115=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(117=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(118=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(119=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(123=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(124=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(128=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(19=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(20=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(21=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(22=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(23=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(24=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(25=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(26=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(27=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(28=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(29=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(30=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(33=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(34=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(35=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(36=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(40=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(44=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(45=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(46=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(47=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(48=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(50=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(52=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(55=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(56=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(58=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(62=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(63=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(64=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(66=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(67=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(69=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(70=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(71=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(72=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(74=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(75=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(76=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(77=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(79=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(80=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(82=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(83=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(89=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(90=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(91=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(92=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(93=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(94=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(95=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(96=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(97=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(98=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(99=S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2(Other, _, _, _, _, _, _) ->$/;" f module:parser +yeccpars2_0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_0(S, '#', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_0(S, '(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_0(S, '...', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_0(S, '<', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_0(S, '[', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_0(S, '\\'', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_0(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_0(S, 'fun(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_0(S, '{', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_0(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_1(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_10 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_10(S, '->', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_10 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_100 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_100(S, ',', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_100 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_100(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_100 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_100(S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_100 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_100(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_101 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_101(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_101_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_101_(__Stack0) ->$/;" f module:parser +yeccpars2_102 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_102(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_102 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_102(S, atom_full, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_102 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_102(S, atom_part, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_102 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_102(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_102 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_102(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_102_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_102_(__Stack0) ->$/;" f module:parser +yeccpars2_103 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_103(S, '[', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_103 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_103(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_105 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_105(S, ',', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_105 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_105(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_105 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_105(S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_105 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_105(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_107 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_107(S, ']', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_107 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_107(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_107 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_107(S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_107 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_107(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_108 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_108(S, ')', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_108 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_108(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_109 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_109(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_109_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_109_(__Stack0) ->$/;" f module:parser +yeccpars2_10_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_10_(__Stack0) ->$/;" f module:parser +yeccpars2_11 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_11(S, '..', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_11 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_11(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_110 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_110(S, '#', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_110 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_110(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_111 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_111(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_111_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_111_(__Stack0) ->$/;" f module:parser +yeccpars2_112 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_112(S, '<', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_112 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_112(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_113 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_113(S, '#', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_113 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_113(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_114 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_114(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_114_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_114_(__Stack0) ->$/;" f module:parser +yeccpars2_116 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_116(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_116_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_116_(__Stack0) ->$/;" f module:parser +yeccpars2_117 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_117(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_117_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_117_(__Stack0) ->$/;" f module:parser +yeccpars2_11_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_11_(__Stack0) ->$/;" f module:parser +yeccpars2_12 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_12(S, '->', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_12 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_12(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_120 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_120(S, '=', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_120 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_120(S, '|', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_120 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_120(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_120_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_120_(__Stack0) ->$/;" f module:parser +yeccpars2_121 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_121(S, '=', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_121 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_121(S, '|', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_121 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_121(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_121_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_121_(__Stack0) ->$/;" f module:parser +yeccpars2_122 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_122(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_122_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_122_(__Stack0) ->$/;" f module:parser +yeccpars2_125 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_125(S, '=', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_125 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_125(S, '|', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_125 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_125(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_125_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_125_(__Stack0) ->$/;" f module:parser +yeccpars2_126 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_126(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_126_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_126_(__Stack0) ->$/;" f module:parser +yeccpars2_127 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_127(S, '(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_127 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_127(S, ':', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_127 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_127(S, '::', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_127 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_127(S, '[', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_127 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_127(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_127 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_127(S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_127 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_127(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_128 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_128(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_128 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_128(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_129 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_129(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_129_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_129_(__Stack0) ->$/;" f module:parser +yeccpars2_12_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_12_(__Stack0) ->$/;" f module:parser +yeccpars2_13 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_13(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_13 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_13(_S, '$end', _Ss, Stack, _T, _Ts, _Tzr) ->$/;" f module:parser +yeccpars2_130 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_130(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_130_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_130_(__Stack0) ->$/;" f module:parser +yeccpars2_14 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_14_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_14_(__Stack0) ->$/;" f module:parser +yeccpars2_15 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_15_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_15_(__Stack0) ->$/;" f module:parser +yeccpars2_16 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_16_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_16_(__Stack0) ->$/;" f module:parser +yeccpars2_17 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_17(S, '(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_17 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_17(S, ':', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_17 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_17(S, '::', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_17 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_17(S, '[', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_17 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_17(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_17 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_17(S, atom_full, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_17 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_17(S, atom_part, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_17 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_17(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_17 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_17(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_17_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_17_(__Stack0) ->$/;" f module:parser +yeccpars2_18 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_18_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_18_(__Stack0) ->$/;" f module:parser +yeccpars2_19 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_19(S, '{', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_19 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_19(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_1_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_1_(__Stack0) ->$/;" f module:parser +yeccpars2_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2(S, '#', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2(S, '(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2(S, '...', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2(S, '<', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2(S, '=', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2(S, '[', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2(S, '\\'', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2(S, 'fun(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2(S, '{', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2(S, '|', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2(S, atom_full, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2(S, atom_part, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_21 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_21(S, '#', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_21 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_21(S, '(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_21 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_21(S, ')', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_21 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_21(S, '...', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_21 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_21(S, '<', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_21 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_21(S, '[', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_21 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_21(S, '\\'', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_21 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_21(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_21 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_21(S, 'fun(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_21 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_21(S, '{', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_21 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_21(S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_21 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_21(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_22 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_22_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_22_(__Stack0) ->$/;" f module:parser +yeccpars2_23 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_23(S, '#', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_23 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_23(S, '(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_23 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_23(S, '...', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_23 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_23(S, '<', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_23 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_23(S, '[', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_23 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_23(S, '\\'', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_23 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_23(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_23 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_23(S, 'fun(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_23 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_23(S, '{', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_23 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_23(S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_23 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_23(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_24 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_24(S, '#', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_24 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_24(S, '(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_24 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_24(S, '...', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_24 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_24(S, '<', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_24 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_24(S, '[', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_24 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_24(S, '\\'', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_24 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_24(S, ']', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_24 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_24(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_24 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_24(S, 'fun(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_24 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_24(S, '{', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_24 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_24(S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_24 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_24(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_25 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_25_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_25_(__Stack0) ->$/;" f module:parser +yeccpars2_26 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_26_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_26_(__Stack0) ->$/;" f module:parser +yeccpars2_27 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_27(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_27_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_27_(__Stack0) ->$/;" f module:parser +yeccpars2_28 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_28(S, '(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_28 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_28(S, ')', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_28 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_28(S, '...', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_28 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_28(S, '[', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_28 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_28(S, 'fun(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_28 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_28(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_29 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_29_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_29_(__Stack0) ->$/;" f module:parser +yeccpars2_2_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_2_(__Stack0) ->$/;" f module:parser +yeccpars2_3 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_3(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_30 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_30(S, '#', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_30 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_30(S, '(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_30 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_30(S, '...', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_30 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_30(S, '<', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_30 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_30(S, '[', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_30 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_30(S, '\\'', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_30 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_30(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_30 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_30(S, 'fun(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_30 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_30(S, '{', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_30 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_30(S, '}', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_30 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_30(S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_30 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_30(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_31 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_31(S, '}', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_31 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_31(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_32 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_32(S, ',', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_32 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_32(S, '=', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_32 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_32(S, '|', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_32 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_32(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_32_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_32_(__Stack0) ->$/;" f module:parser +yeccpars2_33 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_33_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_33_(__Stack0) ->$/;" f module:parser +yeccpars2_37 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_37(S, '=', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_37 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_37(S, '|', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_37 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_37(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_37_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_37_(__Stack0) ->$/;" f module:parser +yeccpars2_38 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_38(S, '=', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_38 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_38(S, '|', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_38 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_38_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_38_(__Stack0) ->$/;" f module:parser +yeccpars2_39 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_39(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_39_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_39_(__Stack0) ->$/;" f module:parser +yeccpars2_3_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_3_(__Stack0) ->$/;" f module:parser +yeccpars2_4 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_4(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_40 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_40_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_40_(__Stack0) ->$/;" f module:parser +yeccpars2_41 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_41(S, '->', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_41 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_41(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_42 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_42(S, '->', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_42 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_42(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_43 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_43(S, ')', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_43 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_43(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_44 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_44(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_44_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_44_(__Stack0) ->$/;" f module:parser +yeccpars2_45 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_45(S, ')', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_45 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_45(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_46 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_46(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_46_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_46_(__Stack0) ->$/;" f module:parser +yeccpars2_47 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_47(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_47_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_47_(__Stack0) ->$/;" f module:parser +yeccpars2_49 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_49(S, '=', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_49 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_49(S, '|', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_49 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_49(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_49_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_49_(__Stack0) ->$/;" f module:parser +yeccpars2_4_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_4_(__Stack0) ->$/;" f module:parser +yeccpars2_5 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_5(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_51 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_51(S, '=', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_51 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_51(S, 'when', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_51 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_51(S, '|', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_51 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_51(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_51_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_51_(__Stack0) ->$/;" f module:parser +yeccpars2_53 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_53(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_53_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_53_(__Stack0) ->$/;" f module:parser +yeccpars2_54 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_54(S, ']', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_54 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_54(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_55 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_55(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_55_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_55_(__Stack0) ->$/;" f module:parser +yeccpars2_56 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_56(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_56_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_56_(__Stack0) ->$/;" f module:parser +yeccpars2_57 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_57(S, '>', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_57 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_57(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_58 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_58(S, '#', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_58 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_58(S, '(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_58 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_58(S, '...', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_58 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_58(S, '<', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_58 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_58(S, '>', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_58 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_58(S, '[', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_58 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_58(S, '\\'', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_58 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_58(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_58 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_58(S, 'fun(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_58 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_58(S, '{', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_58 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_58(S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_58 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_58(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_59 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_59(S, '>', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_59 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_59(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_5_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_5_(__Stack0) ->$/;" f module:parser +yeccpars2_6 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_6(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_60 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_60(S, ',', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_60 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_60(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_60_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_60_(__Stack0) ->$/;" f module:parser +yeccpars2_61 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_61(S, '>', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_61 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_61(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_62 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_62(S, '>', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_62 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_62(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_63 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_63(S, ':', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_63 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_63(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_63_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_63_(__Stack0) ->$/;" f module:parser +yeccpars2_64 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_64(S, '#', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_64 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_64(S, '(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_64 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_64(S, '...', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_64 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_64(S, '<', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_64 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_64(S, '[', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_64 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_64(S, '\\'', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_64 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_64(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_64 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_64(S, 'fun(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_64 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_64(S, '{', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_64 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_64(S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_64 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_64(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_65 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_65(S, '=', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_65 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_65(S, '|', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_65 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_65(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_65_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_65_(__Stack0) ->$/;" f module:parser +yeccpars2_66 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_66(S, '*', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_66 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_66(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_66_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_66_(__Stack0) ->$/;" f module:parser +yeccpars2_68 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_68(S, '=', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_68 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_68(S, '|', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_68 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_68(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_68_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_68_(__Stack0) ->$/;" f module:parser +yeccpars2_69 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_69(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_69_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_69_(__Stack0) ->$/;" f module:parser +yeccpars2_6_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_6_(__Stack0) ->$/;" f module:parser +yeccpars2_7 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_7(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_70 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_70(S, '>', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_70 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_70(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_71 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_71(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_71_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_71_(__Stack0) ->$/;" f module:parser +yeccpars2_72 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_72(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_72 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_72(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_73 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_73(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_73_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_73_(__Stack0) ->$/;" f module:parser +yeccpars2_74 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_74(S, ':', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_74 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_74(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_75 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_75(S, '>', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_75 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_75(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_75_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_75_(__Stack0) ->$/;" f module:parser +yeccpars2_76 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_76(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_76_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_76_(__Stack0) ->$/;" f module:parser +yeccpars2_77 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_77(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_77_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_77_(__Stack0) ->$/;" f module:parser +yeccpars2_78 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_78(S, ')', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_78 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_78(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_79 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_79(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_79_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_79_(__Stack0) ->$/;" f module:parser +yeccpars2_7_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_7_(__Stack0) ->$/;" f module:parser +yeccpars2_8 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_8(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_80 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_80(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_80_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_80_(__Stack0) ->$/;" f module:parser +yeccpars2_81 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_81(S, '=', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_81 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_81(S, '\\'', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_81 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_81(S, '|', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_81 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_81(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_82 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_82(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_82_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_82_(__Stack0) ->$/;" f module:parser +yeccpars2_83 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_83(S, '#', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_83 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_83(S, '(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_83 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_83(S, '...', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_83 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_83(S, '<', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_83 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_83(S, '[', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_83 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_83(S, '\\'', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_83 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_83(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_83 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_83(S, 'fun(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_83 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_83(S, '{', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_83 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_83(S, '}', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_83 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_83(S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_83 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_83(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_84 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_84(S, ':=', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_84 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_84(S, '=', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_84 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_84(S, '=>', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_84 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_84(S, '|', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_84 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_84(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_85 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_85(S, '}', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_85 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_85(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_86 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_86(S, ',', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_86 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_86(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_86_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_86_(__Stack0) ->$/;" f module:parser +yeccpars2_87 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_87(S, '}', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_87 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_87(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_88 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_88(S, ',', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_88 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_88(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_88_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_88_(__Stack0) ->$/;" f module:parser +yeccpars2_89 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_89(S, '<', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_89 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_89(S, '{', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_89 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_89(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_8_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_8_(__Stack0) ->$/;" f module:parser +yeccpars2_9 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_9(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_90 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_90(S, '#', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_90 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_90(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_90_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_90_(__Stack0) ->$/;" f module:parser +yeccpars2_91 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_91(_S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_91_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_91_(__Stack0) ->$/;" f module:parser +yeccpars2_92 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_92(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_92 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_92(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_93 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_93(S, '>', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_93 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_93(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_94 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_94(S, '(', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_94 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_94(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_95 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_95(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_95 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_95(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_96 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_96(S, ',', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_96 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_96(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_97 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_97(S, int, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_97 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_97(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_98 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_98(S, ',', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_98 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_98(_, _, _, _, T, _, _) ->$/;" f module:parser +yeccpars2_99 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_99(S, '_', Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_99 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_99(S, Cat, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_9_ .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_9_(__Stack0) ->$/;" f module:parser +yeccpars2_cont_0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_cont_0(S, atom_full, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_cont_0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_cont_0(S, atom_part, Ss, Stack, T, Ts, Tzr) ->$/;" f module:parser +yeccpars2_cont_0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yeccpars2_cont_0(_, _, _, _, T, _, _) ->$/;" f module:parser +yecctoken2string .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken2string(Token) ->$/;" f module:parser +yecctoken2string1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken2string1(Other) ->$/;" f module:parser +yecctoken2string1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken2string1({'$end', _}) -> [];$/;" f module:parser +yecctoken2string1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken2string1({Other, _}) when is_atom(Other) ->$/;" f module:parser +yecctoken2string1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken2string1({_Cat, _, Val}) -> io_lib:format("~tp", [Val]);$/;" f module:parser +yecctoken2string1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken2string1({atom, _, A}) -> io_lib:write_atom(A);$/;" f module:parser +yecctoken2string1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken2string1({char,_,C}) -> io_lib:write_char(C);$/;" f module:parser +yecctoken2string1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken2string1({dot, _}) -> "'.'";$/;" f module:parser +yecctoken2string1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken2string1({float,_,F}) -> io_lib:write(F);$/;" f module:parser +yecctoken2string1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken2string1({integer,_,N}) -> io_lib:write(N);$/;" f module:parser +yecctoken2string1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken2string1({reserved_symbol, _, A}) -> io_lib:write(A);$/;" f module:parser +yecctoken2string1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken2string1({string,_,S}) -> io_lib:write_string(S);$/;" f module:parser +yecctoken2string1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken2string1({var,_,V}) -> io_lib:format("~s", [V]);$/;" f module:parser +yecctoken_end_location .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken_end_location(Token) ->$/;" f module:parser +yecctoken_location .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken_location(Token) ->$/;" f module:parser +yecctoken_to_string .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/parser.erl /^yecctoken_to_string(Token) ->$/;" f module:parser +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(0, _, _, _) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(1, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(10, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(11, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(12, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(13, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(14, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(15, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(16, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(17, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(18, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(19, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(2, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(20, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(21, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(22, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(23, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(24, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(25, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(26, TokenLen, YYtcs, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(27, TokenLen, YYtcs, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(28, TokenLen, YYtcs, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(29, TokenLen, YYtcs, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(3, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(4, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(5, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(6, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(7, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(8, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(9, _, _, TokenLine) ->$/;" f module:lexer +yyaction .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction(_, _, _, _) -> error.$/;" f module:lexer +yyaction_0 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_0() ->$/;" f module:lexer +yyaction_1 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_1(TokenLine) ->$/;" f module:lexer +yyaction_10 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_10(TokenLine) ->$/;" f module:lexer +yyaction_11 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_11(TokenLine) ->$/;" f module:lexer +yyaction_12 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_12(TokenLine) ->$/;" f module:lexer +yyaction_13 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_13(TokenLine) ->$/;" f module:lexer +yyaction_14 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_14(TokenLine) ->$/;" f module:lexer +yyaction_15 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_15(TokenLine) ->$/;" f module:lexer +yyaction_16 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_16(TokenLine) ->$/;" f module:lexer +yyaction_17 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_17(TokenLine) ->$/;" f module:lexer +yyaction_18 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_18(TokenLine) ->$/;" f module:lexer +yyaction_19 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_19(TokenLine) ->$/;" f module:lexer +yyaction_2 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_2(TokenLine) ->$/;" f module:lexer +yyaction_20 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_20(TokenLine) ->$/;" f module:lexer +yyaction_21 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_21(TokenLine) ->$/;" f module:lexer +yyaction_22 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_22(TokenLine) ->$/;" f module:lexer +yyaction_23 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_23(TokenLine) ->$/;" f module:lexer +yyaction_24 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_24(TokenLine) ->$/;" f module:lexer +yyaction_25 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_25(TokenLine) ->$/;" f module:lexer +yyaction_26 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_26(TokenChars, TokenLine) ->$/;" f module:lexer +yyaction_27 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_27(TokenChars, TokenLine) ->$/;" f module:lexer +yyaction_28 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_28(TokenChars, TokenLine) ->$/;" f module:lexer +yyaction_29 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_29(TokenChars, TokenLine) ->$/;" f module:lexer +yyaction_3 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_3(TokenLine) ->$/;" f module:lexer +yyaction_4 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_4(TokenLine) ->$/;" f module:lexer +yyaction_5 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_5(TokenLine) ->$/;" f module:lexer +yyaction_6 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_6(TokenLine) ->$/;" f module:lexer +yyaction_7 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_7(TokenLine) ->$/;" f module:lexer +yyaction_8 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_8(TokenLine) ->$/;" f module:lexer +yyaction_9 .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyaction_9(TokenLine) ->$/;" f module:lexer +yypre .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yypre(List, N) -> lists:sublist(List, N).$/;" f module:lexer +yyrev .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyrev(List) -> lists:reverse(List).$/;" f module:lexer +yyrev .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yyrev(List, Tail) -> lists:reverse(List, Tail).$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate() -> 41.$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(0, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(0, [10|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(0, [C|Ics], Line, Tlen, _, _) when C >= 0, C =< 9 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(0, [C|Ics], Line, Tlen, _, _) when C >= 11, C =< 38 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(0, [C|Ics], Line, Tlen, _, _) when C >= 40 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(1, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(10, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(11, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(12, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(13, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(14, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(15, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(15, [10|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(15, [119|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(15, [13|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(15, [32|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(15, [9|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(16, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(17, Ics, Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(17, [40|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(18, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(18, [58|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(18, [61|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(19, Ics, Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(19, [104|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(2, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(20, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(21, Ics, Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(21, [110|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(22, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(23, Ics, Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(23, [101|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(24, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(24, [62|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(24, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(25, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(25, [117|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(26, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(27, Ics, Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(27, [110|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(28, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(29, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(3, Ics, Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(3, [10|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(3, [39|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(3, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 9 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(3, [C|Ics], Line, Tlen, Action, Alen) when C >= 11, C =< 38 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(3, [C|Ics], Line, Tlen, Action, Alen) when C >= 40 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(30, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(30, [46|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(30, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(31, Ics, Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(31, [32|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(32, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(32, [46|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(33, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(34, Ics, Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(34, [C|Ics], Line, Tlen, Action, Alen) when C >= 48, C =< 57 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(35, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(36, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(36, [46|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(37, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(38, Ics, Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(38, [101|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(38, [C|Ics], Line, Tlen, Action, Alen) when C >= 48, C =< 57 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(39, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(39, [10|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(39, [13|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(39, [32|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(39, [9|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(4, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(40, Ics, Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(40, [C|Ics], Line, Tlen, Action, Alen) when C >= 48, C =< 57 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, Ics, Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [102|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [10|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [11|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [123|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [124|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [125|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [12|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [13|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [32|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [33|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [34|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [35|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [39|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [40|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [41|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [42|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [43|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [44|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [45|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [46|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [47|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [58|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [59|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [60|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [61|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [62|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [91|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [92|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [93|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [94|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [95|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [9|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [C|Ics], Line, Tlen, Action, Alen) when C >= 0, C =< 8 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [C|Ics], Line, Tlen, Action, Alen) when C >= 103, C =< 122 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [C|Ics], Line, Tlen, Action, Alen) when C >= 126 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [C|Ics], Line, Tlen, Action, Alen) when C >= 14, C =< 31 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [C|Ics], Line, Tlen, Action, Alen) when C >= 36, C =< 38 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [C|Ics], Line, Tlen, Action, Alen) when C >= 48, C =< 57 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [C|Ics], Line, Tlen, Action, Alen) when C >= 63, C =< 90 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(41, [C|Ics], Line, Tlen, Action, Alen) when C >= 96, C =< 101 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(42, Ics, Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(42, [45|Ics], Line, Tlen, Action, Alen) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(42, [C|Ics], Line, Tlen, Action, Alen) when C >= 48, C =< 57 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(43, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(44, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(44, [C|Ics], Line, Tlen, _, _) when C >= 48, C =< 57 ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(5, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(6, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(6, [62|Ics], Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(7, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(8, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(9, Ics, Line, Tlen, _, _) ->$/;" f module:lexer +yystate .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yystate(S, Ics, Line, Tlen, Action, Alen) ->$/;" f module:lexer +yysuf .elixir_ls/elixir.nvim/downloads/elixir-lsp/elixir-ls/tags_v0.10.0/deps/erlex/src/lexer.erl /^yysuf(List, N) -> lists:nthtail(N, List).$/;" f module:lexer diff --git a/elixir/secret-handshake/test/secret_handshake_test.exs b/elixir/secret-handshake/test/secret_handshake_test.exs new file mode 100644 index 0000000..8f488bd --- /dev/null +++ b/elixir/secret-handshake/test/secret_handshake_test.exs @@ -0,0 +1,65 @@ +defmodule SecretHandshakeTest do + use ExUnit.Case + + describe "Create a handshake for a number" do + # @tag :pending + test "wink for 1" do + assert SecretHandshake.commands(1) == ["wink"] + end + + @tag :pending + test "double blink for 10" do + assert SecretHandshake.commands(2) == ["double blink"] + end + + @tag :pending + test "close your eyes for 100" do + assert SecretHandshake.commands(4) == ["close your eyes"] + end + + @tag :pending + test "jump for 1000" do + assert SecretHandshake.commands(8) == ["jump"] + end + + @tag :pending + test "combine two actions" do + assert SecretHandshake.commands(3) == ["wink", "double blink"] + end + + @tag :pending + test "reverse two actions" do + assert SecretHandshake.commands(19) == ["double blink", "wink"] + end + + @tag :pending + test "reversing one action gives the same action" do + assert SecretHandshake.commands(24) == ["jump"] + end + + @tag :pending + test "reversing no actions still gives no actions" do + assert SecretHandshake.commands(16) == [] + end + + @tag :pending + test "all possible actions" do + assert SecretHandshake.commands(15) == ["wink", "double blink", "close your eyes", "jump"] + end + + @tag :pending + test "reverse all possible actions" do + assert SecretHandshake.commands(31) == ["jump", "close your eyes", "double blink", "wink"] + end + + @tag :pending + test "do nothing for zero" do + assert SecretHandshake.commands(0) == [] + end + + @tag :pending + test "do nothing if lower 5 bits not set" do + assert SecretHandshake.commands(32) == [] + end + end +end diff --git a/elixir/secret-handshake/test/test_helper.exs b/elixir/secret-handshake/test/test_helper.exs new file mode 100644 index 0000000..35fc5bf --- /dev/null +++ b/elixir/secret-handshake/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true) diff --git a/elixir/secret-handshake/time.txt b/elixir/secret-handshake/time.txt new file mode 100644 index 0000000..9a6bd77 --- /dev/null +++ b/elixir/secret-handshake/time.txt @@ -0,0 +1,507 @@ + + +times in msec + clock self+sourced self: sourced script + clock elapsed: other lines + +000.006 000.006: --- NVIM STARTING --- +000.110 000.104: event init +000.232 000.122: early init +000.459 000.227: locale set +000.502 000.043: init first window +011.325 010.824: inits 1 +011.345 000.020: window checked +011.523 000.178: parsing arguments +011.984 000.070 000.070: require('vim.shared') +012.116 000.060 000.060: require('vim._meta') +012.119 000.131 000.071: require('vim._editor') +012.121 000.242 000.041: require('vim._init_packages') +012.124 000.359: init lua interpreter +012.387 000.263: expanding arguments +012.472 000.085: inits 2 +012.680 000.207: init highlight +012.681 000.001: waiting for UI +015.375 002.694: done waiting for UI +015.410 000.036: init screen for UI +015.591 000.181: init default mappings +015.604 000.013: init default autocommands +019.160 000.465 000.465: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/ftplugin.vim +019.934 000.380 000.380: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/indent.vim +034.970 000.434 000.434: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/syntax/synload.vim +036.316 000.330 000.330: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/LuaSnip/ftdetect/snippets.vim +037.002 000.384 000.384: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/rust.vim/ftdetect/rust.vim +037.599 000.364 000.364: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/vim-fugitive/ftdetect/fugitive.vim +038.263 002.718 001.640: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/filetype.lua +038.718 000.346 000.346: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/filetype.vim +040.022 001.055 001.055: require('vim.filetype') +042.833 002.044 002.044: require('vim.filetype.detect') +044.553 000.025 000.025: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/ftplugin/elixir.vim +049.204 016.588 009.966: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/syntax/syntax.vim +049.306 028.545 011.957: require('halfdan.settings') +053.035 001.025 001.025: require('packer.util') +053.081 003.120 002.095: require('packer') +054.612 001.528 001.528: require('packer.log') +056.887 000.643 000.643: require('packer.async') +058.465 000.756 000.756: require('packer.result') +058.473 001.580 000.824: require('packer.jobs') +058.482 003.833 001.610: require('packer.plugin_utils') +060.107 001.587 001.587: require('packer.snapshot') +060.541 011.232 001.165: require('halfdan.packer') +063.174 000.918 000.918: require('neogit.config') +066.891 000.653 000.653: require('neogit.lib.notification') +068.446 000.794 000.794: require('plenary.log') +068.472 001.576 000.783: require('neogit.logger') +069.962 000.275 000.275: require('plenary.tbl') +069.967 000.582 000.306: require('plenary.vararg.rotate') +069.969 000.837 000.255: require('plenary.vararg') +070.228 000.257 000.257: require('plenary.errors') +070.524 000.293 000.293: require('plenary.functional') +070.531 001.722 000.335: require('plenary.async.async') +071.809 000.298 000.298: require('plenary.async.structs') +071.816 000.683 000.384: require('plenary.async.control') +071.829 001.021 000.338: require('plenary.async.util') +071.832 001.280 000.259: require('plenary.async.tests') +071.834 003.360 000.358: require('plenary.async') +072.759 000.922 000.922: require('neogit.process') +073.986 000.586 000.586: require('neogit.lib.util') +074.004 001.239 000.653: require('neogit.lib.job') +074.037 009.533 001.782: require('neogit.lib.git.cli') +075.590 000.598 000.598: require('neogit.lib.git.stash') +076.163 000.567 000.567: require('neogit.lib.collection') +076.174 002.134 000.969: require('neogit.lib.git.status') +076.773 000.596 000.596: require('neogit.lib.git.log') +077.897 000.550 000.550: require('neogit.lib.input') +077.906 001.127 000.577: require('neogit.lib.git.branch') +079.943 001.033 001.033: require('neogit.lib.md5') +079.951 001.982 000.948: require('neogit.lib.git.diff') +079.953 016.251 000.879: require('neogit.lib.git') +081.654 000.699 000.699: require('neogit.lib.popup.builder') +083.032 000.458 000.458: require('neogit.lib.mappings_manager') +084.487 000.577 000.577: require('neogit.lib.ui.component') +084.501 001.464 000.888: require('neogit.lib.ui') +084.512 002.851 000.928: require('neogit.lib.buffer') +085.123 000.609 000.609: require('neogit.buffers.common') +086.198 001.063 001.063: require('neogit.lib.popup.lib') +086.205 006.249 001.028: require('neogit.lib.popup') +086.207 023.026 000.525: require('neogit.lib') +086.731 000.522 000.522: require('neogit.lib.signs') +088.780 001.121 001.121: require('neogit.lib.color') +088.790 002.053 000.932: require('neogit.lib.hl') +091.093 000.550 000.550: require('neogit.buffers.git_command_history') +092.091 000.485 000.485: require('neogit.buffers.commit_view.parsing') +092.555 000.460 000.460: require('neogit.buffers.commit_view.ui') +092.560 001.463 000.518: require('neogit.buffers.commit_view') +093.391 000.443 000.443: require('neogit.lib.git.pull') +093.833 000.437 000.437: require('neogit.lib.git.push') +093.839 001.275 000.395: require('neogit.lib.git.repository') +094.305 000.464 000.464: require('neogit.lib.functional') +094.745 000.437 000.437: require('neogit.lib.line_buffer') +095.183 000.433 000.433: require('neogit.lib.fs') +095.361 006.569 001.948: require('neogit.status') +097.796 000.578 000.578: require('neogit.lib.uv') +098.294 000.493 000.493: require('neogit.buffers.commit_editor') +098.303 002.495 001.425: require('neogit.popups.commit') +100.510 000.592 000.592: require('neogit.buffers.log_view.ui') +100.517 001.476 000.884: require('neogit.buffers.log_view') +100.521 002.215 000.739: require('neogit.popups.log') +101.128 000.605 000.605: require('neogit.popups.push') +101.589 000.457 000.457: require('neogit.popups.pull') +102.154 000.560 000.560: require('neogit.popups.stash') +102.738 000.578 000.578: require('neogit.popups.help') +102.744 007.375 000.467: require('neogit.popups') +102.939 041.615 001.152: require('neogit') +103.712 000.770 000.770: require('halfdan.keymap') +104.236 000.014 000.014: require('vim.keymap') +104.327 043.781 001.383: require('halfdan.neogit') +105.468 001.138 001.138: require('halfdan.globals') +111.164 002.114 002.114: require('gruvbox-baby.hsluv') +111.181 003.269 001.154: require('gruvbox-baby.util') +112.622 001.439 001.439: require('gruvbox-baby.theme') +112.629 005.552 000.844: require('gruvbox-baby') +113.086 000.455 000.455: require('gruvbox-baby.config') +113.714 000.621 000.621: require('gruvbox-baby.colors') +114.959 008.451 001.824: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/gruvbox-baby/colors/gruvbox-baby.vim +115.047 009.572 001.121: require('halfdan.colorscheme') +120.637 000.638 000.638: require('vim.treesitter.language') +120.650 002.203 001.566: require('vim.treesitter.query') +126.204 000.982 000.982: require('vim.treesitter.languagetree') +126.263 001.642 000.660: require('vim.treesitter') +126.376 003.047 001.405: require('nvim-treesitter.parsers') +127.820 001.441 001.441: require('nvim-treesitter.utils') +127.834 006.229 001.742: require('nvim-treesitter.ts_utils') +127.843 007.189 000.960: require('nvim-treesitter.tsrange') +128.790 000.945 000.945: require('nvim-treesitter.caching') +128.811 011.855 001.518: require('nvim-treesitter.query') +128.831 013.214 001.360: require('nvim-treesitter.configs') +131.215 000.883 000.883: require('nvim-treesitter.info') +132.742 001.522 001.522: require('nvim-treesitter.shell_command_selectors') +132.776 003.794 001.389: require('nvim-treesitter.install') +134.438 019.388 002.380: require('halfdan.treesitter') +141.111 000.455 000.455: require('plenary.bit') +141.167 000.035 000.035: require('ffi') +141.191 001.418 000.928: require('plenary.path') +141.201 001.885 000.468: require('plenary.strings') +142.021 000.778 000.778: require('telescope.deprecated') +144.038 000.686 000.686: require('telescope.log') +145.584 000.651 000.651: require('plenary.job') +146.231 000.644 000.644: require('telescope.state') +146.242 002.201 000.907: require('telescope.utils') +146.248 004.222 001.336: require('telescope.sorters') +146.259 000.007 000.007: require('vim.F') +146.320 000.047 000.047: require('vim.inspect') +148.295 010.673 003.733: require('telescope.config') +149.273 000.407 000.407: require('plenary.window.border') +149.576 000.300 000.300: require('plenary.window') +149.808 000.230 000.230: require('plenary.popup.utils') +149.815 001.515 000.578: require('plenary.popup') +150.542 000.725 000.725: require('telescope.pickers.scroller') +151.034 000.488 000.488: require('telescope.actions.state') +151.712 000.674 000.674: require('telescope.actions.utils') +153.200 000.718 000.718: require('telescope.actions.mt') +153.228 001.512 000.794: require('telescope.actions.set') +154.834 000.851 000.851: require('telescope.config.resolve') +154.839 001.609 000.758: require('telescope.pickers.entry_display') +155.259 000.418 000.418: require('telescope.from_entry') +155.564 020.273 002.658: require('telescope.actions') +156.549 000.464 000.464: require('telescope._extensions') +156.555 000.987 000.523: require('telescope') +157.761 000.605 000.605: require('telescope.previewers.previewer') +158.797 001.031 001.031: require('telescope.previewers.term_previewer') +161.560 000.450 000.450: require('plenary.context_manager') +162.389 000.408 000.408: require('nvim-treesitter.statusline') +163.065 000.672 000.672: require('nvim-treesitter.query_predicates') +163.070 001.504 000.424: require('nvim-treesitter') +163.075 002.692 000.738: require('telescope.previewers.utils') +166.663 003.586 003.586: require('plenary.filetype') +168.621 001.954 001.954: require('plenary.scandir') +168.738 009.938 001.706: require('telescope.previewers.buffer_previewer') +168.748 012.186 000.612: require('telescope.previewers') +169.900 035.458 002.012: require('halfdan.telescope') +170.400 000.496 000.496: require('halfdan.themes.nord') +170.860 000.457 000.457: require('halfdan.autocmds') +173.291 000.554 000.554: require('dap.utils') +173.338 001.981 001.427: require('dap') +176.316 000.875 000.875: require('dapui.config') +176.322 001.479 000.603: require('dapui.util') +177.377 000.592 000.592: require('dapui.render.canvas') +177.769 000.388 000.388: require('dapui.render.loop') +177.773 001.448 000.468: require('dapui.render') +178.381 000.606 000.606: require('dapui.windows.layout') +178.386 004.142 000.609: require('dapui.windows') +178.389 005.048 000.906: require('dapui') +179.306 000.915 000.915: require('nvim-dap-virtual-text') +179.994 000.562 000.562: require('dapui.config.highlights') +180.714 000.641 000.641: require('dapui.state') +181.071 000.348 000.348: require('dapui.elements.console') +181.615 000.539 000.539: require('dapui.elements.breakpoints') +182.293 000.354 000.354: require('dapui.components.buf_breakpoints') +182.296 000.678 000.324: require('dapui.components.breakpoints') +182.636 000.333 000.333: require('dapui.elements.repl') +182.954 000.313 000.313: require('dapui.elements.scopes') +183.746 000.480 000.480: require('dapui.components.variables') +183.750 000.792 000.312: require('dapui.components.scopes') +184.062 000.308 000.308: require('dapui.elements.stacks') +184.771 000.380 000.380: require('dapui.components.frames') +184.775 000.710 000.330: require('dapui.components.threads') +185.437 000.363 000.363: require('dapui.components.hover') +185.440 000.661 000.297: require('dapui.elements.hover') +185.749 000.306 000.306: require('dapui.elements.watches') +186.244 000.492 000.492: require('dapui.components.watches') +186.723 000.436 000.436: require('halfdan.debugger.elixir') +187.080 016.216 001.156: require('halfdan.debugger') +187.083 166.805 000.523: require('halfdan') +187.085 166.853 000.048: sourcing /Users/fbecker18/.config/nvim/init.lua +187.145 003.842: sourcing vimrc file(s) +190.623 001.656 001.656: sourcing /Users/fbecker18/.config/nvim/plugin/packer_compiled.vim +191.914 000.514 000.514: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/plugin/gzip.vim +192.344 000.313 000.313: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/plugin/health.vim +192.773 000.316 000.316: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/plugin/man.vim +194.841 000.716 000.716: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/pack/dist/opt/matchit/plugin/matchit.vim +195.121 002.256 001.540: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/plugin/matchit.vim +195.560 000.341 000.341: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/plugin/matchparen.vim +196.443 000.780 000.780: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/plugin/netrwPlugin.vim +197.174 000.278 000.278: sourcing /Users/fbecker18/.local/share/nvim/rplugin.vim +197.192 000.630 000.352: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/plugin/rplugin.vim +197.635 000.343 000.343: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/plugin/shada.vim +197.989 000.247 000.247: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/plugin/spellfile.vim +198.327 000.240 000.240: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/plugin/tarPlugin.vim +198.723 000.295 000.295: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/plugin/tohtml.vim +198.957 000.118 000.118: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/plugin/tutor.vim +199.314 000.249 000.249: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/plugin/zipPlugin.vim +203.823 003.439 003.439: require('Comment') +205.190 000.477 000.477: require('Comment.config') +205.896 000.703 000.703: require('Comment.utils') +206.353 000.454 000.454: require('Comment.opfunc') +206.699 000.342 000.342: require('Comment.extra') +206.707 002.880 000.905: require('Comment.api') +206.937 007.260 000.941: sourcing /Users/fbecker18/.config/nvim/plugin/packer_compiled.lua +207.545 004.843: loading rtp plugins +209.876 000.215 000.215: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/Comment.nvim/plugin/Comment.lua +211.088 000.867 000.867: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/editorconfig-vim/plugin/editorconfig.vim +216.475 000.875 000.875: require('legendary.types') +217.541 001.062 001.062: require('legendary.scratchpad') +217.545 005.310 003.373: require('legendary.cmds') +218.516 000.964 000.964: require('legendary.utils') +218.664 006.493 000.218: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/legendary.nvim/plugin/legendary.lua +219.995 000.535 000.535: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/lspsaga.nvim/plugin/lspsaga.lua +222.260 000.522 000.522: require('luasnip.util.types') +222.995 000.732 000.732: require('luasnip.util.ext_opts') +223.488 000.490 000.490: require('luasnip.extras.filetype_functions') +223.971 000.480 000.480: require('luasnip.session') +227.123 001.009 001.009: require('luasnip.util.util') +227.744 000.617 000.617: require('luasnip.nodes.util') +228.197 000.450 000.450: require('luasnip.util.events') +228.208 002.964 000.888: require('luasnip.nodes.node') +228.813 000.603 000.603: require('luasnip.nodes.insertNode') +229.158 000.342 000.342: require('luasnip.nodes.textNode') +229.792 000.630 000.630: require('luasnip.util.mark') +231.494 001.101 001.101: require('luasnip.util._builtin_vars') +231.548 001.752 000.652: require('luasnip.util.environ') +232.120 000.570 000.570: require('luasnip.util.pattern_tokenizer') +232.655 000.531 000.531: require('luasnip.util.dict') +233.261 000.602 000.602: require('luasnip.session.snippet_collection') +233.296 009.319 001.325: require('luasnip.nodes.snippet') +233.832 000.496 000.496: require('luasnip.nodes.functionNode') +234.747 000.911 000.911: require('luasnip.nodes.choiceNode') +235.322 000.572 000.572: require('luasnip.nodes.dynamicNode') +235.855 000.529 000.529: require('luasnip.nodes.restoreNode') +236.276 000.418 000.418: require('luasnip.extras') +236.805 000.524 000.524: require('luasnip.extras.fmt') +237.233 000.425 000.425: require('luasnip.extras.expand_conditions') +238.109 000.282 000.282: require('luasnip.util.functions') +238.114 000.877 000.595: require('luasnip.util.parser') +238.543 000.427 000.427: require('luasnip.nodes.absolute_indexer') +238.890 018.016 001.293: require('luasnip.config') +238.959 018.493 000.477: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/LuaSnip/plugin/luasnip.vim +241.236 000.559 000.559: require('plenary.reload') +241.418 001.325 000.766: require('plenary') +241.421 001.628 000.304: require('neogit.bootstrap') +241.489 002.037 000.409: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/neogit/plugin/neogit.vim +242.732 000.379 000.379: require('cmp.utils.api') +243.589 000.383 000.383: require('cmp.types.cmp') +244.536 000.502 000.502: require('cmp.utils.misc') +244.550 000.958 000.456: require('cmp.types.lsp') +244.804 000.252 000.252: require('cmp.types.vim') +244.807 002.072 000.479: require('cmp.types') +245.277 000.468 000.468: require('cmp.utils.highlight') +246.138 000.439 000.439: require('cmp.utils.debug') +246.146 000.867 000.427: require('cmp.utils.autocmd') +246.420 004.182 000.395: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/nvim-cmp/plugin/cmp.lua +246.987 000.096 000.096: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/nvim-dap/plugin/dap.lua +248.066 000.422 000.422: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/nvim-lsp-installer/plugin/nvim-lsp-installer.vim +254.692 001.045 001.045: require('vim.lsp.log') +256.216 001.520 001.520: require('vim.lsp.protocol') +258.570 000.766 000.766: require('vim.lsp._snippet') +259.087 000.513 000.513: require('vim.highlight') +259.104 002.885 001.606: require('vim.lsp.util') +259.127 006.273 000.823: require('vim.lsp.handlers') +259.956 000.826 000.826: require('vim.lsp.rpc') +260.555 000.596 000.596: require('vim.lsp.sync') +261.562 001.003 001.003: require('vim.lsp.buf') +262.142 000.577 000.577: require('vim.lsp.diagnostic') +262.760 000.615 000.615: require('vim.lsp.codelens') +262.908 011.792 001.901: require('vim.lsp') +262.963 012.768 000.976: require('lspconfig.util') +262.967 013.456 000.688: require('lspconfig.configs') +262.970 014.019 000.563: require('lspconfig') +263.018 014.449 000.430: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/nvim-lspconfig/plugin/lspconfig.vim +265.427 000.643 000.643: require('vim.treesitter.highlighter') +265.438 001.282 000.639: require('nvim-treesitter.highlight') +265.573 001.924 000.642: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/nvim-treesitter/plugin/nvim-treesitter.lua +266.700 000.552 000.552: require('nvim-treesitter-textobjects') +268.048 000.488 000.488: require('nvim-treesitter.textobjects.shared') +268.052 001.000 000.512: require('nvim-treesitter.textobjects.select') +268.739 000.315 000.315: require('nvim-treesitter.textobjects.attach') +268.744 000.674 000.359: require('nvim-treesitter.textobjects.move') +269.157 000.314 000.314: require('nvim-treesitter.textobjects.swap') +269.548 000.356 000.356: require('nvim-treesitter.textobjects.lsp_interop') +269.566 003.701 000.805: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/nvim-treesitter-textobjects/plugin/nvim-treesitter-textobjects.vim +270.334 000.332 000.332: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/nvim-web-devicons/plugin/nvim-web-devicons.vim +271.250 000.318 000.318: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/plenary.nvim/plugin/plenary.vim +272.173 000.334 000.334: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/rust.vim/plugin/cargo.vim +272.476 000.180 000.180: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/rust.vim/plugin/rust.vim +274.212 001.270 001.270: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/tagbar/plugin/tagbar.vim +275.597 000.646 000.646: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/telescope.nvim/plugin/telescope.lua +277.603 001.696 001.696: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/vim-dispatch/plugin/dispatch.vim +278.730 000.658 000.658: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/vim-easy-align/plugin/easy_align.vim +280.568 001.398 001.398: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/vim-fugitive/plugin/fugitive.vim +282.459 000.537 000.537: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/vim-gitgutter/autoload/gitgutter/utility.vim +283.652 000.602 000.602: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/vim-gitgutter/autoload/gitgutter/highlight.vim +284.215 003.127 001.987: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/vim-gitgutter/plugin/gitgutter.vim +285.010 000.372 000.372: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/vim-highlightedyank/plugin/highlightedyank.vim +286.738 001.340 001.340: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/vim-sneak/plugin/sneak.vim +288.108 000.976 000.976: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/vim-surround/plugin/surround.vim +289.788 000.610 000.610: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/vim-test/autoload/test.vim +290.505 001.997 001.387: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/vim-test/plugin/test.vim +290.865 015.262: loading packages +294.721 000.556 000.556: require('cmp.utils.char') +294.731 000.905 000.349: require('cmp.utils.str') +295.220 000.487 000.487: require('cmp.utils.pattern') +296.659 000.262 000.262: require('cmp.utils.buffer') +296.667 001.118 000.856: require('cmp.utils.keymap') +296.673 001.450 000.331: require('cmp.utils.feedkeys') +296.976 000.302 000.302: require('cmp.utils.async') +297.543 000.266 000.266: require('cmp.utils.cache') +297.550 000.571 000.305: require('cmp.context') +299.072 000.452 000.452: require('cmp.config.mapping') +300.219 000.816 000.816: require('cmp.config.compare') +300.222 001.146 000.330: require('cmp.config.default') +300.238 002.094 000.496: require('cmp.config') +301.423 000.495 000.495: require('cmp.matcher') +301.428 001.188 000.694: require('cmp.entry') +301.433 003.881 000.599: require('cmp.source') +302.391 000.465 000.465: require('cmp.utils.event') +303.391 000.518 000.518: require('cmp.utils.window') +303.395 001.001 000.483: require('cmp.view.docs_view') +304.154 000.758 000.758: require('cmp.view.custom_entries_view') +304.835 000.678 000.678: require('cmp.view.wildmenu_entries_view') +305.297 000.460 000.460: require('cmp.view.native_entries_view') +305.814 000.514 000.514: require('cmp.view.ghost_text_view') +305.823 004.389 000.514: require('cmp.view') +305.912 013.118 001.133: require('cmp.core') +306.509 000.459 000.459: require('cmp.config.sources') +306.950 000.437 000.437: require('cmp.config.window') +307.018 014.861 000.846: require('cmp') +309.088 000.384 000.384: require('cmp_buffer.timer') +309.094 001.217 000.832: require('cmp_buffer.buffer') +309.100 001.697 000.480: require('cmp_buffer.source') +309.121 002.101 000.404: require('cmp_buffer') +309.145 017.032 000.071: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/cmp-buffer/after/plugin/cmp_buffer.lua +310.185 000.744 000.744: require('cmp_cmdline') +310.248 000.849 000.105: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/cmp-cmdline/after/plugin/cmp_cmdline.lua +311.409 000.424 000.424: require('cmp_nvim_lsp.source') +311.412 000.892 000.468: require('cmp_nvim_lsp') +311.465 000.984 000.092: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/cmp-nvim-lsp/after/plugin/cmp_nvim_lsp.lua +312.596 000.785 000.785: require('cmp_path') +312.635 000.881 000.096: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/cmp-path/after/plugin/cmp_path.lua +314.149 000.430 000.430: require('cmp_tabnine.config') +314.167 001.024 000.595: require('cmp_tabnine.source') +314.169 001.261 000.237: require('cmp_tabnine') +314.172 001.303 000.042: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/cmp-tabnine/after/plugin/cmp-tabnine.lua +315.275 000.818 000.818: require('cmp_luasnip') +315.336 000.928 000.110: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/cmp_luasnip/after/plugin/cmp_luasnip.lua +316.899 000.880 000.880: require('lspkind') +319.095 000.510 000.510: require('luasnip.loaders._caches') +319.099 000.947 000.437: require('luasnip.loaders') +319.139 002.237 001.290: require('luasnip') +319.998 004.075 000.958: sourcing /Users/fbecker18/.config/nvim/after/plugin/cmp.lua +320.200 000.058 000.058: sourcing /Users/fbecker18/.config/nvim/after/plugin/init.lua +321.691 001.365 001.365: sourcing /Users/fbecker18/.config/nvim/after/plugin/keymappings.lua +324.889 000.229 000.229: require('plenary.functional') +324.896 000.978 000.750: require('plenary.job') +325.829 000.312 000.312: require('plenary.bit') +325.846 000.948 000.636: require('plenary.path') +326.829 000.284 000.284: require('plenary.strings') +326.833 000.610 000.326: require('plenary.window.border') +327.023 000.188 000.188: require('plenary.window') +327.210 000.185 000.185: require('plenary.popup.utils') +327.214 001.367 000.383: require('plenary.popup') +327.482 000.267 000.267: require('elixir.version') +328.724 000.838 000.838: require('plenary.curl') +329.023 000.296 000.296: require('elixir.utils') +329.027 001.540 000.406: require('elixir.download') +329.884 000.855 000.855: require('elixir.compile') +330.540 000.651 000.651: require('lspconfig.server_configurations.elixirls') +330.790 008.231 001.625: require('elixir') +332.041 000.556 000.556: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/vim-gitgutter/autoload/gitgutter.vim +333.383 000.912 000.912: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/vim-gitgutter/autoload/gitgutter/sign.vim +334.481 000.701 000.701: sourcing /Users/fbecker18/.local/share/nvim/site/pack/packer/start/vim-gitgutter/autoload/gitgutter/hunk.vim +336.526 000.601 000.601: require('lspconfig.server_configurations.gopls') +337.485 000.656 000.656: require('lspconfig.server_configurations.julials') +338.492 000.696 000.696: require('lspconfig.server_configurations.rust_analyzer') +339.286 000.670 000.670: require('lspconfig.server_configurations.pyright') +340.245 000.848 000.848: require('rust-tools') +341.848 000.763 000.763: require('rust-tools.utils.utils') +341.855 001.606 000.842: require('rust-tools.code_action_group') +342.562 000.705 000.705: require('rust-tools.commands') +344.868 000.667 000.667: require('rust-tools/executors/termopen') +345.512 000.640 000.640: require('rust-tools/executors/quickfix') +345.969 000.454 000.454: require('rust-tools/executors/toggleterm') +345.973 002.412 000.651: require('rust-tools/executors') +345.978 003.412 001.000: require('rust-tools.config') +346.655 000.676 000.676: require('rust-tools.crate_graph') +347.388 000.729 000.729: require('rust-tools.dap') +347.878 000.486 000.486: require('rust-tools.debuggables') +348.353 000.471 000.471: require('rust-tools.expand_macro') +348.794 000.437 000.437: require('rust-tools.external_docs') +349.291 000.493 000.493: require('rust-tools.hover_actions') +349.743 000.449 000.449: require('rust-tools.hover_range') +350.514 000.768 000.768: require('rust-tools.inlay_hints') +350.979 000.458 000.458: require('rust-tools.join_lines') +352.189 000.409 000.409: require('rust-tools.server_status') +352.195 001.213 000.804: require('rust-tools.lsp') +352.668 000.434 000.434: require('rust-tools.move_item') +353.117 000.446 000.446: require('rust-tools.open_cargo_toml') +353.558 000.437 000.437: require('rust-tools.parent_module') +354.045 000.484 000.484: require('rust-tools.runnables') +354.516 000.466 000.466: require('rust-tools.ssr') +354.997 000.478 000.478: require('rust-tools.standalone') +355.275 000.274 000.274: require('rust-tools.workspace_refresh') +355.634 000.264 000.264: require('rust-tools/workspace_refresh') +356.048 034.251 005.194: sourcing /Users/fbecker18/.config/nvim/after/plugin/lsp.lua +356.975 000.663 000.663: require('lspsaga') +360.246 000.614 000.614: require('lspsaga.wrap') +360.252 001.835 001.221: require('lspsaga.window') +360.283 002.576 000.741: require('lspsaga.libs') +360.310 003.330 000.754: require('lspsaga.lightbulb') +361.003 000.675 000.675: require('lspsaga.lspkind') +362.036 000.965 000.965: require('lspsaga.symbolwinbar') +362.062 005.867 000.235: sourcing /Users/fbecker18/.config/nvim/after/plugin/lspsaga.lua +362.267 000.074 000.074: sourcing /Users/fbecker18/.config/nvim/after/plugin/sneak.lua +362.441 000.047 000.047: sourcing /Users/fbecker18/.config/nvim/after/plugin/tagbar.lua +365.653 000.257 000.257: require('plenary.tbl') +365.659 000.548 000.291: require('plenary.vararg.rotate') +365.661 000.790 000.242: require('plenary.vararg') +365.907 000.244 000.244: require('plenary.errors') +365.912 001.351 000.317: require('plenary.async.async') +366.203 000.288 000.288: require('plenary.async.structs') +366.210 002.019 000.380: require('plenary.async.control') +368.596 001.163 001.163: require('telescope.make_entry') +370.139 000.318 000.318: require('plenary.async.util') +370.144 000.572 000.254: require('plenary.async.tests') +370.146 000.856 000.285: require('plenary.async') +370.149 001.550 000.693: require('telescope.finders.async_static_finder') +372.493 000.642 000.642: require('plenary.class') +372.926 000.430 000.430: require('plenary.log') +372.939 002.306 001.234: require('telescope._') +372.941 002.790 000.484: require('telescope.finders.async_oneshot_finder') +373.419 000.476 000.476: require('telescope.finders.async_job_finder') +373.425 007.212 001.233: require('telescope.finders') +375.492 000.680 000.680: require('telescope.debounce') +376.143 000.648 000.648: require('telescope.mappings') +376.879 000.732 000.732: require('telescope.pickers.highlights') +377.330 000.447 000.447: require('telescope.pickers.window') +379.415 001.057 001.057: require('telescope.algos.linked_list') +379.420 002.087 001.031: require('telescope.entry_manager') +380.066 000.645 000.645: require('telescope.pickers.multi') +380.081 006.654 001.415: require('telescope.pickers') +380.086 016.750 000.865: require('telescope.builtin.lsp') +380.108 017.500 000.749: require('telescope.builtin') +380.181 017.636 000.136: sourcing /Users/fbecker18/.config/nvim/after/plugin/telescope.lua +786.167 001.015 001.015: require('nvim-treesitter.locals') +786.174 001.749 000.734: require('nvim-treesitter.incremental_selection') +787.455 000.874 000.874: require('nvim-treesitter.indent') +793.194 000.021 000.021: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/ftplugin/elixir.vim +798.125 000.464 000.464: require('luasnip.util.path') +799.023 000.894 000.894: require('luasnip.loaders.util') +799.531 000.505 000.505: require('luasnip.util.str') +799.538 002.528 000.665: require('luasnip.loaders.from_lua') +800.535 000.386 000.386: require('luasnip.nodes.snippetProxy') +800.541 000.972 000.586: require('luasnip.loaders.from_snipmate') +801.552 000.981 000.981: require('luasnip.loaders.from_vscode') +1533.228 000.752 000.752: require('vim.uri') +1535.655 000.021 000.021: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/ftplugin/elixir.vim +1547.041 001.948 001.948: require('nvim-web-devicons') +1553.182 1172.889 1163.044: sourcing /Users/fbecker18/.config/nvim/after/plugin/treesitter-textobjects.lua +1553.205 004.100: loading after plugins +1553.248 000.043: inits 3 +1556.157 002.909: reading ShaDa +1556.209 000.053: opening buffers +1558.479 002.270: BufEnter autocommands +1558.489 000.009: editing files in windows +1559.476 000.987: VimEnter autocommands +1559.495 000.019: UIEnter autocommands +1560.803 000.827 000.827: sourcing /Users/fbecker18/.asdf/installs/neovim/nightly/share/nvim/runtime/autoload/provider/clipboard.vim +1560.830 000.508: before starting main loop +2248.041 687.211: first screen update +2248.044 000.003: --- NVIM STARTED --- diff --git a/elixir/take-a-number/.exercism/config.json b/elixir/take-a-number/.exercism/config.json new file mode 100644 index 0000000..9e2e943 --- /dev/null +++ b/elixir/take-a-number/.exercism/config.json @@ -0,0 +1,21 @@ +{ + "authors": [ + "angelikatyborska" + ], + "contributors": [ + "neenjaw" + ], + "files": { + "solution": [ + "lib/take_a_number.ex" + ], + "test": [ + "test/take_a_number_test.exs" + ], + "exemplar": [ + ".meta/exemplar.ex" + ] + }, + "language_versions": ">=1.10", + "blurb": "Learn about processes and process identifiers by writing an embedded system for a Take-A-Number machine." +} diff --git a/elixir/take-a-number/.exercism/metadata.json b/elixir/take-a-number/.exercism/metadata.json new file mode 100644 index 0000000..d2b4708 --- /dev/null +++ b/elixir/take-a-number/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"take-a-number","id":"b2fcfcd6cdb644318950e405d687e28c","url":"https://exercism.org/tracks/elixir/exercises/take-a-number","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/take-a-number/.formatter.exs b/elixir/take-a-number/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/take-a-number/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/take-a-number/.gitignore b/elixir/take-a-number/.gitignore new file mode 100644 index 0000000..cb54963 --- /dev/null +++ b/elixir/take-a-number/.gitignore @@ -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"). +nil-*.tar + diff --git a/elixir/take-a-number/HELP.md b/elixir/take-a-number/HELP.md new file mode 100644 index 0000000..b3eeca6 --- /dev/null +++ b/elixir/take-a-number/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/take_a_number.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/take-a-number/HINTS.md b/elixir/take-a-number/HINTS.md new file mode 100644 index 0000000..47cac84 --- /dev/null +++ b/elixir/take-a-number/HINTS.md @@ -0,0 +1,40 @@ +# Hints + +## General + +- Read about processes in the official [Getting Started guide][getting-started-processes]. +- Read [this blog post][mullen-processes] about Elixir processes. + +## 1. Start the machine + +- The machine should run in a new process. There is [a built-in function that starts a new process][kernel-spawn-1]. +- You will need another function that the new process will execute. + +## 2. Report the machine state + +- The machine's process needs to respond to messages. +- There is [a built-in function that waits for a message to arrive in the process's mailbox][kernel-receive]. +- There is [a built-in function that sends a message to another process][kernel-send]. +- Use recursion to wait for more than one message. +- Pass the machine's state as an argument to the recursive function. + +## 3. Give out numbers + +- This step is conceptually the same as the previous step. The only difference is the need to update the machine's state. + +## 4. Stop the machine + +- This step doesn't require sending any messages as a response. +- A process will exit if it has no more code to execute. +- This is a base case of the recursive function. + +## 5. Ignore unexpected messages + +- This step doesn't require sending any messages as a response. +- You can use `_` to match all messages that didn't match previous patterns. + +[getting-started-processes]: https://elixir-lang.org/getting-started/processes.html +[mullen-processes]: https://samuelmullen.com/articles/elixir-processes-send-and-receive/ +[kernel-spawn-1]: https://hexdocs.pm/elixir/Kernel.html#spawn/1 +[kernel-receive]: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#receive/1 +[kernel-send]: https://hexdocs.pm/elixir/Kernel.html#send/2 \ No newline at end of file diff --git a/elixir/take-a-number/README.md b/elixir/take-a-number/README.md new file mode 100644 index 0000000..5d9b5ca --- /dev/null +++ b/elixir/take-a-number/README.md @@ -0,0 +1,114 @@ +# Take-A-Number + +Welcome to Take-A-Number 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 + +## Processes + +In Elixir, all code runs inside processes. + +By default, a function will execute in the same process from which it was called. When you need to explicitly run a certain function in a new process, use `spawn/1`: + +```elixir +spawn(fn -> 2 + 2 end) +# => #PID<0.125.0> +``` + +`spawn/1` creates a new process that executes the given function and returns a _process identifier_ (PID). The new process will stay alive as long as the function executes, and then silently exit. + +Elixir's processes should not be confused with operating system processes. Elixir's processes use much less memory and CPU. It's perfectly fine to have Elixir applications that run hundreds of Elixir processes. + +### Messages + +Processes do not directly share information with one another. Processes _send and receive messages_ to share data. + +You can send a message to any process with `send/2`. The first argument to `send/2` is the PID of the recipient, the second argument is the message. + +A message can be of any type. Often it consists of atoms and tuples. If you want to get a response, you should include the PID of the sender somewhere in the message. You can get the PID of the current process with `self()`. + +`send/2` does not check if the message was received by the recipient, nor if the recipient is still alive. The message ends up in the recipient's _mailbox_ and it will only be read if and when the recipient explicitly asks to _receive messages_. + +A message can be read from a mailbox using the `receive/1` macro. It accepts a `do` block that can [pattern match][exercism-pattern-matching] on the messages. + +```elixir +receive do + {:ping, sender_pid} -> send(sender_pid, :pong) + :do_nothing -> nil +end +``` + +`receive/1` will take _one message_ from the mailbox that matches any of the given patterns and execute the expression given for that pattern. If there are no messages in the mailbox, or none of messages in the mailbox match any of the patterns, `receive/1` is going to wait for one. + +### Receive loop + +If you want to receive more than one message, you need to call `receive/1` recursively. It is a common pattern to implement a recursive function, for example named `loop`, that calls `receive/1`, does something with the message, and then calls itself to wait for more messages. If you need to carry some state from one `receive/1` call to another, you can do it by passing an argument to that `loop` function. + +## PIDs + +Process identifiers are their own data type. They function as _mailbox addresses_ - if you have a process's PID, you can send a message to that process. PIDs are usually created indirectly, as a return value of functions that create new processes, like `spawn`. + +[exercism-pattern-matching]: https://exercism.org/tracks/elixir/concepts/pattern-matching + +## Instructions + +You are writing an embedded system for a Take-A-Number machine. It is a very simple model. It can give out consecutive numbers and report what was the last number given out. + +## 1. Start the machine + +Implement the `start/0` function. It should spawn a new process that has an initial state of `0` and is ready to receive messages. It should return the process's PID. + +```elixir +TakeANumber.start() +# => #PID<0.138.0> +``` + +Note that each time you run this code, the PID may be different. + +## 2. Report the machine state + +Modify the machine so that it can receive `{:report_state, sender_pid}` messages. It should send its current state (the last given out ticket number) to `sender_pid` and then wait for more messages. + +```elixir +machine_pid = TakeANumber.start() +send(machine_pid, {:report_state, self()}) + +receive do + msg -> msg +end +# => 0 +``` + +## 3. Give out numbers + +Modify the machine so that it can receive `{:take_a_number, sender_pid}` messages. It should increase its state by 1, send the new state to `sender_pid`, and then wait for more messages. + +```elixir +machine_pid = TakeANumber.start() +send(machine_pid, {:take_a_number, self()}) + +receive do + msg -> msg +end +# => 1 +``` + +## 4. Stop the machine + +Modify the machine so that it can receive a `:stop` message. It should stop waiting for more messages. + +## 5. Ignore unexpected messages + +Modify the machine so that when it receives an unexpected message, it ignores it and continues waiting for more messages. + +## Source + +### Created by + +- @angelikatyborska + +### Contributed to by + +- @neenjaw \ No newline at end of file diff --git a/elixir/take-a-number/lib/take_a_number.ex b/elixir/take-a-number/lib/take_a_number.ex new file mode 100644 index 0000000..6642a98 --- /dev/null +++ b/elixir/take-a-number/lib/take_a_number.ex @@ -0,0 +1,24 @@ +defmodule TakeANumber do + def start() do + spawn(fn -> loop(0) end) + end + + defp loop(state) do + receive do + {:report_state, sender_pid} -> + send(sender_pid, state) + loop(state) + + {:take_a_number, sender_pid} -> + state = state + 1 + send(sender_pid, state) + loop(state) + + :stop -> + nil + + _ -> + loop(state) + end + end +end diff --git a/elixir/take-a-number/mix.exs b/elixir/take-a-number/mix.exs new file mode 100644 index 0000000..36ac6a6 --- /dev/null +++ b/elixir/take-a-number/mix.exs @@ -0,0 +1,28 @@ +defmodule TakeANumber.MixProject do + use Mix.Project + + def project do + [ + app: :take_a_number, + 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 diff --git a/elixir/take-a-number/test/take_a_number_test.exs b/elixir/take-a-number/test/take_a_number_test.exs new file mode 100644 index 0000000..7867300 --- /dev/null +++ b/elixir/take-a-number/test/take_a_number_test.exs @@ -0,0 +1,96 @@ +defmodule TakeANumberTest do + use ExUnit.Case + + @tag task_id: 1 + test "starts a new process" do + pid = TakeANumber.start() + assert is_pid(pid) + assert pid != self() + assert pid != TakeANumber.start() + end + + @tag task_id: 2 + test "reports its own state" do + pid = TakeANumber.start() + send(pid, {:report_state, self()}) + assert_receive 0 + end + + @tag task_id: 2 + test "does not shut down after reporting its own state" do + pid = TakeANumber.start() + send(pid, {:report_state, self()}) + assert_receive 0 + + send(pid, {:report_state, self()}) + assert_receive 0 + end + + @tag task_id: 3 + test "gives out a number" do + pid = TakeANumber.start() + send(pid, {:take_a_number, self()}) + assert_receive 1 + end + + @tag task_id: 3 + test "gives out many consecutive numbers" do + pid = TakeANumber.start() + send(pid, {:take_a_number, self()}) + assert_receive 1 + + send(pid, {:take_a_number, self()}) + assert_receive 2 + + send(pid, {:take_a_number, self()}) + assert_receive 3 + + send(pid, {:report_state, self()}) + assert_receive 3 + + send(pid, {:take_a_number, self()}) + assert_receive 4 + + send(pid, {:take_a_number, self()}) + assert_receive 5 + + send(pid, {:report_state, self()}) + assert_receive 5 + end + + @tag task_id: 4 + test "stops" do + pid = TakeANumber.start() + assert Process.alive?(pid) + send(pid, {:report_state, self()}) + assert_receive 0 + + send(pid, :stop) + send(pid, {:report_state, self()}) + refute_receive 0 + refute Process.alive?(pid) + end + + @tag task_id: 5 + test "ignores unexpected messages and keeps working" do + pid = TakeANumber.start() + + send(pid, :hello?) + send(pid, "I want to speak with the manager") + + send(pid, {:take_a_number, self()}) + assert_receive 1 + + send(pid, {:report_state, self()}) + assert_receive 1 + + # This is necessary because `Process.info/1` is not guaranteed to return up-to-date info immediately. + dirty_hacky_delay_to_ensure_up_to_date_process_info = 200 + :timer.sleep(dirty_hacky_delay_to_ensure_up_to_date_process_info) + + # Do not use `Process.info/1` in your own code. + # It's meant for debugging purposes only. + # We use it here for didactic purposes because there is no alternative that would achieve the same result. + assert Keyword.get(Process.info(pid), :message_queue_len) == 0 + end +end diff --git a/elixir/take-a-number/test/test_helper.exs b/elixir/take-a-number/test/test_helper.exs new file mode 100644 index 0000000..e8677a3 --- /dev/null +++ b/elixir/take-a-number/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true, seed: 0) diff --git a/elixir/top-secret/.exercism/config.json b/elixir/top-secret/.exercism/config.json new file mode 100644 index 0000000..fbefcdb --- /dev/null +++ b/elixir/top-secret/.exercism/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "jiegillet", + "angelikatyborska" + ], + "files": { + "solution": [ + "lib/top_secret.ex" + ], + "test": [ + "test/top_secret_test.exs" + ], + "exemplar": [ + ".meta/exemplar.ex" + ] + }, + "language_versions": ">=1.10", + "blurb": "Learn about the Abstract Syntax Tree (AST) by helping decode secret messages from Agent Ex." +} diff --git a/elixir/top-secret/.exercism/metadata.json b/elixir/top-secret/.exercism/metadata.json new file mode 100644 index 0000000..1f8b365 --- /dev/null +++ b/elixir/top-secret/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"elixir","exercise":"top-secret","id":"3dad9554b77a486aaa5d6788da42ffe3","url":"https://exercism.org/tracks/elixir/exercises/top-secret","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/elixir/top-secret/.formatter.exs b/elixir/top-secret/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/elixir/top-secret/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/elixir/top-secret/.gitignore b/elixir/top-secret/.gitignore new file mode 100644 index 0000000..a0f694e --- /dev/null +++ b/elixir/top-secret/.gitignore @@ -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"). +maps-*.tar + diff --git a/elixir/top-secret/HELP.md b/elixir/top-secret/HELP.md new file mode 100644 index 0000000..2dd7718 --- /dev/null +++ b/elixir/top-secret/HELP.md @@ -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/.exs:LINENUM` - runs only a single test, the test from `.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/top_secret.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) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- 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. +If you can't find what you're looking for in the documentation, feel free to ask help in the Exercism's BEAM [gitter channel](https://gitter.im/exercism/xerlang). \ No newline at end of file diff --git a/elixir/top-secret/HINTS.md b/elixir/top-secret/HINTS.md new file mode 100644 index 0000000..045ffd4 --- /dev/null +++ b/elixir/top-secret/HINTS.md @@ -0,0 +1,51 @@ +# Hints + +## General + +- Read about quoting in the [official Getting Started guide][getting-started-quote]. +- Read the [introduction to Elixir AST by Lucas San Román][ast-intro-lucas]. +- Read [the official documentation for `quote`][doc-quote]. +- Inspect the output of [`quote`][doc-quote] to familiarize yourself with how ASTs look like for specific code snippets. + +## 1. Turn code into data + +- There is a [built-in function][doc-code-string-to-quoted] that turns a string with code into an AST. + +## 2. Parse a single AST node + +- Inspect the output of [`quote`][doc-quote] to familiarize yourself with how ASTs look like for specific code snippets. +- The operations that define a function are `:def` and `:defp`. +- The operation is the first element in a three-element AST node tuple. +- You can ignore the second element in the tuple in this exercise completely. +- The third element in the tuple is the argument list of the operation that defines the function. +- The first element on that list is a tuple with the function's name and arguments, and the second element is the function's body. + +## 3. Decode the secret message part from function definition + +- Inspect the output of [`quote`][doc-quote] to familiarize yourself with how ASTs look like for specific code snippets. +- The AST node that contains the function's name also contains the function's argument list as the third element. +- The arity of a function is the length of its argument list. +- There is a [built-in function in the `String` module][string-slice] that can get the first `n` characters from a string. +- A function without arguments written without parentheses will not have a list as argument but an atom. + +## 4. Fix the decoding for functions with guards + +- Inspect the output of [`quote`][doc-quote] to familiarize yourself with how ASTs look like for specific code snippets. +- When a function has a guard, the third element in the tuple for the `:def/:defp` operation is a bit different. +- That third element is a list with two elements, the first one is the tuple for the `:when` operation, and the second one is the function's body. +- The `:when` operation's arguments are a two-element list, where the first argument is the function's name, and the second is the guard expression. + +## 5. Decode the full secret message + +- Use the function `to_ast/1` that you implemented in the first task to create the AST. +- There is a [built-in function][macro-prewalk] that can visit each node in an AST with an accumulator. +- Use the function `decode_secret_message_part/2` that you implemented in previous tasks to prewalk the AST. +- To reverse the accumulator at the end and turn it into a string, refresh your knowledge of the [`Enum` module][enum]. + +[getting-started-quote]: https://elixir-lang.org/getting-started/meta/quote-and-unquote.html#quoting +[doc-quote]: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#quote/2 +[ast-intro-lucas]: https://dorgan.ar/posts/2021/04/the_elixir_ast/ +[doc-code-string-to-quoted]: https://hexdocs.pm/elixir/Code.html#string_to_quoted/2 +[string-slice]: https://hexdocs.pm/elixir/String.html#slice/2 +[macro-prewalk]: https://hexdocs.pm/elixir/Macro.html#prewalk/3 +[enum]: https://hexdocs.pm/elixir/Enum.html \ No newline at end of file diff --git a/elixir/top-secret/README.md b/elixir/top-secret/README.md new file mode 100644 index 0000000..8e50bce --- /dev/null +++ b/elixir/top-secret/README.md @@ -0,0 +1,137 @@ +# Top Secret + +Welcome to Top Secret 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 + +## AST + +The Abstract Syntax Tree (AST), also called a _quoted expression_, is a way to represent code as data. + +Each node in the AST is a three-element tuple. + +```elixir +# AST representation of: +# 2 + 3 +{:+, [], [2, 3]} +``` + +The first element, an atom, is the operation. The second element, a keyword list, is the metadata. The third element is a list of arguments, which contains other nodes. Literal values such as integers, atoms, and strings are represented in the AST as themselves instead of three-element tuples. + +### Turning code into ASTs + +Changing Elixir code to ASTs and ASTs back to code is part of the standard library. You can find functions for working with ASTs in the modules `Code` (e.g. to change a string with code to an AST) and `Macro` (e.g. to traverse the AST or change it to a string). + +Note that all of the functions in the standard library use the name "quoted" to mean the AST (short for _quoted expression_). + +The special form for turning code into an AST is called `quote`. It accepts a code block and returns its AST. + +```elixir +quote do + 2 + 3 - 1 +end + +# => {:-, [], [ +# {:+, [], [2, 3]}, +# 1 +# ]} +``` + +### Use cases + +The ability to represent code as an AST is at the heart of metaprogramming in Elixir. _Macros_, which is a way to write Elixir code that produces Elixir code, work by returning ASTs as output. + +Another use case for ASTs is static code analysis, like Exercism's own tool, the Analyzer, which you might already know as the little bot that leaves comments on your solutions. + +## Instructions + +You're part of a task force fighting against corporate espionage. You have a secret informer at Shady Company X, which you suspect of stealing secrets from its competitors. + +Your informer, Agent Ex, is an Elixir developer. She is encoding secret messages in her code. + +To decode her secret messages: + +- Take all functions (public and private) in the order they're defined in. +- For each function, take the first `n` characters from its name, where `n` is the function's arity. + +## 1. Turn code into data + +Implement the `TopSecret.to_ast/1` function. It should take a string with Elixir code and return its AST. + +```elixir +TopSecret.to_ast("div(4, 3)") +# => {:div, [line: 1], [4, 3]} +``` + +## 2. Parse a single AST node + +Implement the `TopSecret.decode_secret_message_part/2` function. It should take an AST node and an accumulator for the secret message (a list). It should return a tuple with the AST node unchanged as the first element, and the accumulator as the second element. + +If the operation of the AST node is defining a function (`def` or `defp`), prepend the function name (changed to a string) to the accumulator. If the operation is something else, return the accumulator unchanged. + +```elixir +ast_node = TopSecret.to_ast("defp cat(a, b, c), do: nil") +TopSecret.decode_secret_message_part(ast_node, ["day"]) +# => {ast_node, ["cat", "day"]} + +ast_node = TopSecret.to_ast("10 + 3") +TopSecret.decode_secret_message_part(ast_node, ["day"]) +# => {ast_node, ["day"]} +``` + +This function doesn't need to do any recursive calls to check the whole AST, only the given node. We will traverse the whole AST with built-in tools in the last step. + +## 3. Decode the secret message part from function definition + +Extend the `TopSecret.decode_secret_message_part/2` function. If the operation in the AST node is defining a function, don't return the whole function name. Instead, check the function's arity. Then, return only first `n` character from the name, where `n` is the arity. + +```elixir +ast_node = TopSecret.to_ast("defp cat(a, b), do: nil") +TopSecret.decode_secret_message_part(ast_node, ["day"]) +# => {ast_node, ["ca", "day"]} + +ast_node = TopSecret.to_ast("defp cat(), do: nil") +TopSecret.decode_secret_message_part(ast_node, ["day"]) +# => {ast_node, ["", "day"]} +``` + +## 4. Fix the decoding for functions with guards + +Extend the `TopSecret.decode_secret_message_part/2` function. Make sure the function's name and arity is correctly detected for function definitions that use guards. + +```elixir +ast_node = TopSecret.to_ast("defp cat(a, b) when is_nil(a), do: nil") +TopSecret.decode_secret_message_part(ast_node, ["day"]) +# => {ast_node, ["ca", "day"]} +``` + +## 5. Decode the full secret message + +Implement the `TopSecret.decode_secret_message/1` function. It should take a string with Elixir code and return the secret message as a string decoded from all function definitions found in the code. Make sure to reuse functions defined in previous steps. + +```elixir +code = """ +defmodule MyCalendar do + def busy?(date, time) do + Date.day_of_week(date) != 7 and + time.hour in 10..16 + end + + def yesterday?(date) do + Date.diff(Date.utc_today, date) + end +end +""" + +TopSecret.decode_secret_message(code) +# => "buy" +``` + +## Source + +### Created by + +- @jiegillet +- @angelikatyborska \ No newline at end of file diff --git a/elixir/top-secret/lib/top_secret.ex b/elixir/top-secret/lib/top_secret.ex new file mode 100644 index 0000000..53f5ed1 --- /dev/null +++ b/elixir/top-secret/lib/top_secret.ex @@ -0,0 +1,16 @@ +defmodule TopSecret do + def to_ast(string) do + case Code.string_to_quoted(string) do + {:ok, ast} -> ast + _ -> "Error" + end + end + + def decode_secret_message_part(ast, acc) do + # Please implement the decode_secret_message_part/2 function + end + + def decode_secret_message(string) do + # Please implement the decode_secret_message/1 function + end +end diff --git a/elixir/top-secret/mix.exs b/elixir/top-secret/mix.exs new file mode 100644 index 0000000..e670bb8 --- /dev/null +++ b/elixir/top-secret/mix.exs @@ -0,0 +1,28 @@ +defmodule TopSecret.MixProject do + use Mix.Project + + def project do + [ + app: :top_secret, + 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 diff --git a/elixir/top-secret/test/test_helper.exs b/elixir/top-secret/test/test_helper.exs new file mode 100644 index 0000000..e8677a3 --- /dev/null +++ b/elixir/top-secret/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true, seed: 0) diff --git a/elixir/top-secret/test/top_secret_test.exs b/elixir/top-secret/test/top_secret_test.exs new file mode 100644 index 0000000..2ce163f --- /dev/null +++ b/elixir/top-secret/test/top_secret_test.exs @@ -0,0 +1,280 @@ +defmodule TopSecretTest do + use ExUnit.Case + + describe "to_ast/1" do + @tag task_id: 1 + test "handles an empty string" do + string = "" + ast = {:__block__, [], []} + + assert TopSecret.to_ast(string) == ast + end + + @tag task_id: 1 + test "handles a small code snippet" do + string = """ + x = 7 + y = x - 2 + """ + + ast = + {:__block__, [], + [ + {:=, [line: 1], [{:x, [line: 1], nil}, 7]}, + {:=, [line: 2], [{:y, [line: 2], nil}, {:-, [line: 2], [{:x, [line: 2], nil}, 2]}]} + ]} + + assert TopSecret.to_ast(string) == ast + end + + @tag task_id: 1 + test "handles a bigger code snippet" do + string = """ + defmodule List do + @spec delete([], any) :: [] + @spec delete([...], any) :: list + def delete(list, element) + end + """ + + ast = { + :defmodule, + [line: 1], + [ + {:__aliases__, [line: 1], [:List]}, + [ + do: { + :__block__, + [], + [ + {:@, [line: 2], + [ + {:spec, [line: 2], + [{:"::", [line: 2], [{:delete, [line: 2], [[], {:any, [line: 2], nil}]}, []]}]} + ]}, + {:@, [line: 3], + [ + {:spec, [line: 3], + [ + {:"::", [line: 3], + [ + {:delete, [line: 3], [[{:..., [line: 3], nil}], {:any, [line: 3], nil}]}, + {:list, [line: 3], nil} + ]} + ]} + ]}, + {:def, [line: 4], + [{:delete, [line: 4], [{:list, [line: 4], nil}, {:element, [line: 4], nil}]}]} + ] + } + ] + ] + } + + assert TopSecret.to_ast(string) == ast + end + end + + describe "decode_secret_message_part/2" do + @tag task_id: 2 + test "returns the AST and accumulator unchanged" do + string = "2 + 3" + ast = TopSecret.to_ast(string) + acc = ["le", "mo"] + + {actual_ast, actual_acc} = TopSecret.decode_secret_message_part(ast, acc) + assert actual_ast == ast + assert actual_acc == acc + end + + @tag task_id: 2 + test "appends a public function name to the accumulator" do + string = "def fit(a, b, c), do: :scale" + ast = TopSecret.to_ast(string) + acc = ["at"] + + {actual_ast, actual_acc} = TopSecret.decode_secret_message_part(ast, acc) + assert actual_ast == ast + assert actual_acc == ["fit", "at"] + end + + @tag task_id: 2 + test "appends a private function name to the accumulator" do + string = "defp op(a, b), do: 2" + ast = TopSecret.to_ast(string) + acc = ["e", "ced"] + + {actual_ast, actual_acc} = TopSecret.decode_secret_message_part(ast, acc) + assert actual_ast == ast + assert actual_acc == ["op", "e", "ced"] + end + + @tag task_id: 2 + test "ignores not top-level function definition" do + string = """ + defmodule Math do + def sin(x), do: do_sin(x) + defp do_sin(x), do: nil + end + """ + + ast = TopSecret.to_ast(string) + acc = [] + + {actual_ast, actual_acc} = TopSecret.decode_secret_message_part(ast, acc) + assert actual_ast == ast + assert actual_acc == acc + end + + @tag task_id: 3 + test "function arity affects message part length" do + string = "def adjust(a, b), do: :scale" + ast = TopSecret.to_ast(string) + acc = ["re"] + + {actual_ast, actual_acc} = TopSecret.decode_secret_message_part(ast, acc) + assert actual_ast == ast + assert actual_acc == ["ad", "re"] + end + + @tag task_id: 3 + test "function arity 0 results in empty string" do + string = "def adjust(), do: :scale" + ast = TopSecret.to_ast(string) + acc = ["re"] + + {actual_ast, actual_acc} = TopSecret.decode_secret_message_part(ast, acc) + assert actual_ast == ast + assert actual_acc == ["", "re"] + end + + @tag task_id: 3 + test "function arity 0 and no parentheses results in empty string" do + string = "def adjust, do: :scale" + ast = TopSecret.to_ast(string) + acc = ["re"] + + {actual_ast, actual_acc} = TopSecret.decode_secret_message_part(ast, acc) + assert actual_ast == ast + assert actual_acc == ["", "re"] + end + + @tag task_id: 4 + test "works for public functions with a guard" do + string = "def sign(a) when a >= 0, do: :+" + ast = TopSecret.to_ast(string) + acc = ["e"] + + {actual_ast, actual_acc} = TopSecret.decode_secret_message_part(ast, acc) + assert actual_ast == ast + assert actual_acc == ["s", "e"] + end + + @tag task_id: 4 + test "works for private functions with a guard" do + string = "defp do_sign(a) when a < 0, do: :-" + ast = TopSecret.to_ast(string) + acc = ["e"] + + {actual_ast, actual_acc} = TopSecret.decode_secret_message_part(ast, acc) + assert actual_ast == ast + assert actual_acc == ["d", "e"] + end + end + + describe "decode_secret_message/1" do + @tag task_id: 5 + test "decodes a secret message from a single function definition" do + code = """ + defmodule Notebook do + def note(notebook, text) do + add_to_notebook(notebook, text, append: true) + end + end + """ + + secret_message = "no" + + assert TopSecret.decode_secret_message(code) == secret_message + end + + @tag task_id: 5 + test "decodes a secret message from a two function definitions" do + code = """ + defmodule MyCalendar do + def busy?(date, time) do + Date.day_of_week(date) != 7 and + time.hour in 10..16 + end + + def yesterday?(date) do + Date.diff(Date.utc_today, date) + end + end + """ + + secret_message = "buy" + + assert TopSecret.decode_secret_message(code) == secret_message + end + + @tag task_id: 5 + test "decodes a secret message from many function definitions" do + code = """ + defmodule TotallyNotTopSecret do + def force(mass, acceleration), do: mass * acceleration + def uniform(from, to), do: rand.uniform(to - from) + from + def data(%{metadata: metadata}, _opts), do: model(metadata) + defp model(metadata, _opts), do: metadata |> less_data |> Enum.reverse() |> Enum.take(3) + defp less_data(data, _opts), do: Enum.reject(data, &is_nil/1) + end + """ + + secret_message = "foundamole" + + assert TopSecret.decode_secret_message(code) == secret_message + end + + @tag task_id: 5 + test "decodes a secret message without a module definition" do + code = """ + def force(mass, acceleration), do: mass * acceleration + def uniform(from, to), do: rand.uniform(to - from) + from + def data(%{metadata: metadata}, _opts), do: model(metadata) + defp model(metadata, _opts), do: metadata |> less_data |> Enum.reverse() |> Enum.take(3) + defp less_data(data, _opts), do: Enum.reject(data, &is_nil/1) + """ + + secret_message = "foundamole" + + assert TopSecret.decode_secret_message(code) == secret_message + end + + @tag task_id: 5 + test "decodes another secret message from multiple modules" do + code = """ + defmodule IOHelpers do + def inspect(x, opts), do: IO.inspect(x, opts) + def vi_or_vim(_env, _preference), do: :vim + def signal(pid, string), do: send(pid, {:signal, string}) + def black(text, label), do: IO.ANSI.black <> label <> text <> IO.ANSI.reset() + end + + defmodule TimeHelpers do + defp est_to_cet(time), do: Time.add(time, 6 * 60 * 60) + end + + defmodule ASTHelpers do + def submodule?(m, _f, _args), do: String.contains?(m, ".") + def module({m, _f, _args}), do: m + def arity(_m, _f, args), do: length(args) + defp nested?(x, y) when is_list(y), do: x in y + end + """ + + secret_message = "invisiblesubmarine" + + assert TopSecret.decode_secret_message(code) == secret_message + end + end +end diff --git a/go/blackjack/.exercism/config.json b/go/blackjack/.exercism/config.json new file mode 100644 index 0000000..382f438 --- /dev/null +++ b/go/blackjack/.exercism/config.json @@ -0,0 +1,22 @@ +{ + "blurb": "Learn about conditionals by playing Blackjack.", + "authors": [ + "andres-zartab" + ], + "contributors": [ + "tehsphinx", + "andrerfcsantos" + ], + "forked_from": [], + "files": { + "solution": [ + "blackjack.go" + ], + "test": [ + "blackjack_test.go" + ], + "exemplar": [ + ".meta/exemplar.go" + ] + } +} diff --git a/go/blackjack/.exercism/metadata.json b/go/blackjack/.exercism/metadata.json new file mode 100644 index 0000000..525f894 --- /dev/null +++ b/go/blackjack/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"blackjack","id":"97a16a05d3a141a19fdb0db49be634a3","url":"https://exercism.org/tracks/go/exercises/blackjack","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/go/blackjack/HELP.md b/go/blackjack/HELP.md new file mode 100644 index 0000000..7a89995 --- /dev/null +++ b/go/blackjack/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit blackjack.go` 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 [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/go/blackjack/HINTS.md b/go/blackjack/HINTS.md new file mode 100644 index 0000000..acb09c2 --- /dev/null +++ b/go/blackjack/HINTS.md @@ -0,0 +1,39 @@ +# Hints + +## General + +- Conditionals are used to check for certain conditions and/or criteria. The most basic way of performing a conditional operation is using a single `if` statement. + +## 1. Calculate the score of any given card. + +- The `ParseCard` function should take the `card` string (e.g. `ace`) and turn it into its value (e.g. 11). +- Use a big [`switch` statement][switch_statement] on the `card` variable. +- King, Queen, Jack and 10 can be handled with a single case. +- The switch can have a `default` case. In any case the function should return `0` for unknown cards. + +## 2. Determine if two cards make up a Blackjack. + +- `IsBlackJack` checks if 2 cards have the combined value of 21. +- Should use the `ParseCard` function to get the value for each card. +- Should sum up the values of the 2 cards. +- Should return `true` if the sum is equal to `21`. +- No `if` statement is needed here. The result for the comparison can be returned. + +## 3. Implement the decision logic for hand scores larger than 20 points. + +- As the `LargeHand` function is only called for hands with a value larger than 20, there are only 2 different possible hands: A **BlackJack** with a total value of `21` and **2 Aces** with a total value of `22`. +- The function should check [if][if_statement] `isBlackJack` is `true` and return "P" otherwise. +- If `isBlackJack` is `true`, the dealerScore needs to be checked for being lower than 10. [If][if_statement] it is lower, return "W" otherwise "S". + +## 4. Implement the decision logic for hand scores with less than 21 points. + +- The `SmallHand` function is only called if there are no Aces on the hand (`handScore` is less than 21). +- Implement every condition using [logical operators][logical_operators] if necessary. +- [If][if_statement] your cards sum up to 17 or higher you should always _stand_. +- [If][if_statement] your cards sum up to 11 or lower you should always _hit_. +- [If][if_statement] your cards sum up to a value within the range [12, 16] you should always _stand_ if the dealer has a 6 or lower. +- [If][if_statement] your cards sum up to a value within the range [12, 16] you should always _hit_ if the dealer has a 7 or higher. + +[logical_operators]: https://golang.org/ref/spec#Logical_operators +[if_statement]: https://golang.org/ref/spec#If_statements +[switch_statement]: https://golang.org/ref/spec#Switch_statements \ No newline at end of file diff --git a/go/blackjack/README.md b/go/blackjack/README.md new file mode 100644 index 0000000..7df5b32 --- /dev/null +++ b/go/blackjack/README.md @@ -0,0 +1,134 @@ +# Blackjack + +Welcome to Blackjack on Exercism's Go 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 + +Like other languages, Go also provides a `switch` statement. Switch statements are a shorter way to write long `if ... else if` statements. To make a switch, we start by using the keyword `switch` followed by a value or expression. We then declare each one of the conditions with the `case` keyword. We can also declare a `default` case, that will run when none of the previous `case` conditions matched: + +```go +operatingSystem := "windows" + +switch operatingSystem { +case "windows": + // do something if the operating system is windows +case "linux": + // do something if the operating system is linux +case "macos": + // do something if the operating system is macos +default: + // do something if the operating system is none of the above +} +``` + +One interesting thing about switch statements, is that the value after the `switch` keyword can be omitted, and we can have boolean conditions for each `case`: + +```go +age := 21 + +switch { +case age > 20 && age < 30: + // do something if age is between 20 and 30 +case age == 10: + // do something if age is equal to 10 +default: + // do something else for every other case +} +``` + +## Instructions + +In this exercise we will simulate the first turn of a [Blackjack](https://en.wikipedia.org/wiki/Blackjack) game. + +You will receive two cards and will be able to see the face up card of the dealer. All cards are represented using a string such as "ace", "king", "three", "two", etc. The values of each card are: + +| card | value | card | value | +| :---: | :---: | :---: | :---: | +| ace | 11 | eight | 8 | +| two | 2 | nine | 9 | +| three | 3 | ten | 10 | +| four | 4 | jack | 10 | +| five | 5 | queen | 10 | +| six | 6 | king | 10 | +| seven | 7 | other | 0 | + +**Note**: Commonly, aces can take the value of 1 or 11 but for simplicity we will assume that they can only take the value of 11. + +Depending on your two cards and the card of the dealer, there is a strategy for the first turn of the game, in which you have the following options: + + - Stand (S) + - Hit (H) + - Split (P) + - Automatically win (W) + +Although not optimal yet, you will follow the strategy your friend Alex has been developing, which is as follows: + +Category: Large Hand + +- If you have a pair of aces you must always split them. +- If you have a Blackjack (two cards that sum up to a value of 21), and the dealer does not have an ace, a figure or a ten then you automatically win. If the dealer does have any of those cards then you'll have to stand and wait for the reveal of the other card. + +Category: Small Hand + +- If your cards sum up to 17 or higher you should always stand. +- If your cards sum up to 11 or lower you should always hit. +- If your cards sum up to a value within the range [12, 16] you should always stand unless the dealer has a 7 or higher, in which case you should always hit. + +The overall logic has already been implemented. You have four tasks: + +## 1. Calculate the score of any given card. + +Implement a function to calculate the numerical value of a card given its name using conditionals. + +```go +value := ParseCard("ace") +fmt.Println(value) +// Output: 11 +``` + +## 2. Determine if two cards make up a Blackjack. + +Implement a function that returns `true` if two cards form a Blackjack, `false` otherwise. + +```go +isBlackjack := IsBlackjack("queen", "ace") +fmt.Println(isBlackjack) +// Output: true +``` + +## 3. Implement the decision logic for hand scores larger than 20 points. + +Implement a function that returns the string representation of a decision given your cards. This function is only called if the `handScore` is larger than 20. It will receive 2 arguments: `isBlackJack` and `dealerScore`. It should implement the bulletpoints in the category "Large Hand" above. + +```go +isBlackJack := true +dealerScore := 7 +choice := LargeHand(isBlackJack, dealerScore) +fmt.Println(choice) +// Output: "W" +``` + +## 4. Implement the decision logic for hand scores with less than 21 points. + +Implement a function that returns the string representation of a decision given your cards. This function is only called if the `handScore` is less than 21. It will receive 2 arguments: `handScore` and `dealerScore`. It should implement the bulletpoints in the category "Small Hand" above. + +```go +handScore := 15 +dealerScore := 12 +choice := SmallHand(handScore, dealerScore) +fmt.Println(choice) +// Output: "H" +``` + +## Source + +### Created by + +- @andres-zartab + +### Contributed to by + +- @tehsphinx +- @andrerfcsantos \ No newline at end of file diff --git a/go/blackjack/blackjack.go b/go/blackjack/blackjack.go new file mode 100644 index 0000000..878f3c5 --- /dev/null +++ b/go/blackjack/blackjack.go @@ -0,0 +1,55 @@ +package blackjack + +// ParseCard returns the integer value of a card following blackjack ruleset. +func ParseCard(card string) int { + switch card { + case "ace": + return 11 + case "two": + return 2 + case "three": + return 3 + case "four": + return 4 + case "five": + return 5 + case "six": + return 6 + case "seven": + return 7 + case "eight": + return 8 + case "nine": + return 9 + case "ten", "jack", "queen", "king": + return 10 + default: + return 0 + } +} + +// IsBlackjack returns true if the player has a blackjack, false otherwise. +func IsBlackjack(card1, card2 string) bool { + return ParseCard(card1) + ParseCard(card2) == 21 +} + +// LargeHand implements the decision tree for hand scores larger than 20 points. +func LargeHand(isBlackjack bool, dealerScore int) string { + if !isBlackjack { + // Must have two aces + return "P" + } else if isBlackjack && dealerScore < 10 { + return "W" + } + return "S" +} + +// SmallHand implements the decision tree for hand scores with less than 21 points. +func SmallHand(handScore, dealerScore int) string { + if handScore >= 17 { + return "S" + } else if handScore <= 11 || dealerScore >= 7 { + return "H" + } + return "S" +} diff --git a/go/blackjack/blackjack_test.go b/go/blackjack/blackjack_test.go new file mode 100644 index 0000000..366526e --- /dev/null +++ b/go/blackjack/blackjack_test.go @@ -0,0 +1,398 @@ +package blackjack + +import "testing" + +func TestParseCard(t *testing.T) { + tests := []struct { + name string + card string + want int + }{ + { + name: "parse ace", + card: "ace", + want: 11, + }, + { + name: "parse two", + card: "two", + want: 2, + }, + { + name: "parse three", + card: "three", + want: 3, + }, + { + name: "parse four", + card: "four", + want: 4, + }, + { + name: "parse five", + card: "five", + want: 5, + }, + { + name: "parse six", + card: "six", + want: 6, + }, + { + name: "parse seven", + card: "seven", + want: 7, + }, + { + name: "parse eight", + card: "eight", + want: 8, + }, + { + name: "parse nine", + card: "nine", + want: 9, + }, + { + name: "parse ten", + card: "ten", + want: 10, + }, + { + name: "parse jack", + card: "jack", + want: 10, + }, + { + name: "parse queen", + card: "queen", + want: 10, + }, + { + name: "parse king", + card: "king", + want: 10, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ParseCard(tt.card); got != tt.want { + t.Errorf("ParseCard(%s) = %d, want %d", tt.card, got, tt.want) + } + }) + } +} + +func TestBlackjack(t *testing.T) { + type hand struct { + card1, card2 string + } + tests := []struct { + name string + hand hand + want bool + }{ + { + name: "blackjack with ten (ace first)", + hand: hand{card1: "ace", card2: "ten"}, + want: true, + }, + { + name: "blackjack with jack (ace first)", + hand: hand{card1: "ace", card2: "jack"}, + want: true, + }, + { + name: "blackjack with queen (ace first)", + hand: hand{card1: "ace", card2: "queen"}, + want: true, + }, + { + name: "blackjack with king (ace first)", + hand: hand{card1: "ace", card2: "king"}, + want: true, + }, + { + name: "blackjack with ten (ace second)", + hand: hand{card2: "ace", card1: "ten"}, + want: true, + }, + { + name: "blackjack with jack (ace second)", + hand: hand{card2: "ace", card1: "jack"}, + want: true, + }, + { + name: "blackjack with queen (ace second)", + hand: hand{card2: "ace", card1: "queen"}, + want: true, + }, + { + name: "blackjack with king (ace second)", + hand: hand{card2: "ace", card1: "king"}, + want: true, + }, + { + name: "no blackjack with ace and five", + hand: hand{card2: "ace", card1: "five"}, + want: false, + }, + { + name: "no blackjack with ace and nine", + hand: hand{card2: "ace", card1: "nine"}, + want: false, + }, + { + name: "no blackjack with two aces", + hand: hand{card2: "ace", card1: "ace"}, + want: false, + }, + { + name: "no blackjack with two figures", + hand: hand{card2: "queen", card1: "jack"}, + want: false, + }, + { + name: "no blackjack with king and five", + hand: hand{card2: "king", card1: "five"}, + want: false, + }, + { + name: "no blackjack with eight and five", + hand: hand{card2: "eight", card1: "five"}, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := IsBlackjack(tt.hand.card1, tt.hand.card2); got != tt.want { + t.Errorf("IsBlackjack(%s, %s) = %t, want %t", tt.hand.card1, tt.hand.card2, got, tt.want) + } + }) + } +} + +func TestFirstTurn(t *testing.T) { + type hand struct { + card1, card2 string + } + tests := []struct { + name string + hand hand + dealer string + want string + }{ + { + name: "pair of aces", + hand: hand{card1: "ace", card2: "ace"}, + dealer: "ace", + want: "P", + }, + { + name: "pair of jacks", + hand: hand{card1: "jack", card2: "jack"}, + dealer: "ace", + want: "S", + }, + { + name: "pair of kings", + hand: hand{card1: "king", card2: "king"}, + dealer: "ace", + want: "S", + }, + { + name: "pair of twos", + hand: hand{card1: "two", card2: "two"}, + dealer: "ace", + want: "H", + }, + { + name: "pair of fives", + hand: hand{card1: "five", card2: "five"}, + dealer: "ace", + want: "H", + }, + { + name: "blackjack with ace for dealer", + hand: hand{card1: "ace", card2: "jack"}, + dealer: "ace", + want: "S", + }, + { + name: "blackjack with queen for dealer", + hand: hand{card1: "king", card2: "ace"}, + dealer: "queen", + want: "S", + }, + { + name: "blackjack with five for dealer", + hand: hand{card1: "ace", card2: "ten"}, + dealer: "five", + want: "W", + }, + { + name: "blackjack with nine for dealer", + hand: hand{card1: "ace", card2: "king"}, + dealer: "nine", + want: "W", + }, + { + name: "score of 20", + hand: hand{card1: "ten", card2: "king"}, + dealer: "ace", + want: "S", + }, + { + name: "score of 19", + hand: hand{card1: "ten", card2: "nine"}, + dealer: "ace", + want: "S", + }, + { + name: "score of 18", + hand: hand{card1: "ten", card2: "eight"}, + dealer: "ace", + want: "S", + }, + { + name: "score of 17", + hand: hand{card1: "seven", card2: "king"}, + dealer: "ace", + want: "S", + }, + { + name: "score of 16 with six for dealer", + hand: hand{card1: "ten", card2: "six"}, + dealer: "six", + want: "S", + }, + { + name: "score of 16 with seven for dealer", + hand: hand{card1: "ten", card2: "six"}, + dealer: "seven", + want: "H", + }, + { + name: "score of 16 with ace for dealer", + hand: hand{card1: "ten", card2: "six"}, + dealer: "ace", + want: "H", + }, + { + name: "score of 15 with six for dealer", + hand: hand{card1: "ten", card2: "five"}, + dealer: "six", + want: "S", + }, + { + name: "score of 15 with seven for dealer", + hand: hand{card1: "ten", card2: "five"}, + dealer: "seven", + want: "H", + }, + { + name: "score of 15 with king for dealer", + hand: hand{card1: "ten", card2: "five"}, + dealer: "king", + want: "H", + }, + { + name: "score of 14 with six for dealer", + hand: hand{card1: "ten", card2: "four"}, + dealer: "six", + want: "S", + }, + { + name: "score of 14 with seven for dealer", + hand: hand{card1: "ten", card2: "four"}, + dealer: "seven", + want: "H", + }, + { + name: "score of 14 with queen for dealer", + hand: hand{card1: "ten", card2: "four"}, + dealer: "queen", + want: "H", + }, + { + name: "score of 13 with six for dealer", + hand: hand{card1: "ten", card2: "three"}, + dealer: "six", + want: "S", + }, + { + name: "score of 13 with seven for dealer", + hand: hand{card1: "ten", card2: "three"}, + dealer: "seven", + want: "H", + }, + { + name: "score of 13 with queen for dealer", + hand: hand{card1: "ten", card2: "three"}, + dealer: "queen", + want: "H", + }, + { + name: "score of 12 with six for dealer", + hand: hand{card1: "ten", card2: "two"}, + dealer: "six", + want: "S", + }, + { + name: "score of 12 with seven for dealer", + hand: hand{card1: "ten", card2: "two"}, + dealer: "seven", + want: "H", + }, + { + name: "score of 12 with queen for dealer", + hand: hand{card1: "ten", card2: "two"}, + dealer: "queen", + want: "H", + }, + { + name: "score of 11 with queen for dealer", + hand: hand{card1: "nine", card2: "two"}, + dealer: "queen", + want: "H", + }, + { + name: "score of 10 with two for dealer", + hand: hand{card1: "eight", card2: "two"}, + dealer: "two", + want: "H", + }, + { + name: "score of 5 with queen for dealer", + hand: hand{card1: "three", card2: "two"}, + dealer: "queen", + want: "H", + }, + { + name: "score of 4 with five for dealer", + hand: hand{card1: "two", card2: "two"}, + dealer: "five", + want: "H", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := FirstTurn(tt.hand.card1, tt.hand.card2, tt.dealer); got != tt.want { + t.Errorf("FirstTurn(%s, %s, %s) = %s, want %s", tt.hand.card1, tt.hand.card2, tt.dealer, got, tt.want) + } + }) + } +} + +// FirstTurn returns the semi-optimal decision for the first turn, given the cards of the player and the dealer. +// This function is already implemented and does not need to be edited. It pulls the other functions together in a +// complete decision tree for the first turn. +func FirstTurn(card1, card2, dealerCard string) string { + handScore := ParseCard(card1) + ParseCard(card2) + dealerScore := ParseCard(dealerCard) + + if 20 < handScore { + return LargeHand(IsBlackjack(card1, card2), dealerScore) + } + return SmallHand(handScore, dealerScore) +} diff --git a/go/blackjack/go.mod b/go/blackjack/go.mod new file mode 100644 index 0000000..7a34f8f --- /dev/null +++ b/go/blackjack/go.mod @@ -0,0 +1,3 @@ +module blackjack + +go 1.13 diff --git a/go/chessboard/.exercism/config.json b/go/chessboard/.exercism/config.json new file mode 100644 index 0000000..85dcca2 --- /dev/null +++ b/go/chessboard/.exercism/config.json @@ -0,0 +1,22 @@ +{ + "blurb": "Learn about iterating ranges by generating a chessboard.", + "authors": [ + "brugnara", + "tehsphinx" + ], + "contributors": [], + "forked_from": [ + "elixir/chessboard" + ], + "files": { + "solution": [ + "chessboard.go" + ], + "test": [ + "chessboard_test.go" + ], + "exemplar": [ + ".meta/exemplar.go" + ] + } +} diff --git a/go/chessboard/.exercism/metadata.json b/go/chessboard/.exercism/metadata.json new file mode 100644 index 0000000..4bc07b5 --- /dev/null +++ b/go/chessboard/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"chessboard","id":"72b4b3b0b72f42d8b27bc4cfa8f18090","url":"https://exercism.org/tracks/go/exercises/chessboard","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/go/chessboard/HELP.md b/go/chessboard/HELP.md new file mode 100644 index 0000000..338d65e --- /dev/null +++ b/go/chessboard/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit chessboard.go` 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 [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/go/chessboard/HINTS.md b/go/chessboard/HINTS.md new file mode 100644 index 0000000..103df4d --- /dev/null +++ b/go/chessboard/HINTS.md @@ -0,0 +1,34 @@ +# Hints + +## General + +- An [integer value][integers] can be defined as one or more consecutive digits. +- A [map value][maps] stores key-value data + +## 1. Given a Chessboard and a Rank, count how many squares are occupied + +- You can iterate a [map][maps] +- Check if the value is true. If it is increment. This is to count pieces. +- You have to [explicitly return an integer][return] from a function. + +## 2. Given a Chessboard and a File, count how many squares are occupied + +- You'll first need to check the file is within range. +- Loop over the chessboard. +- Add one if the square is occupied. + +## 3. Count how many squares are present in the given chessboard + +- There are many ways to solve this. +- This should return how many squares are configured in a chess-board. + +## 4. Count how many squares are occupied in the given chessboard + +- Get the CountInRank for all ranks in the chessboard. + +[functions]: https://golang.org/ref/spec#Function_declarations +[return]: https://golang.org/ref/spec#Return_statements +[operators]: https://golang.org/ref/spec#Operators +[integers]: https://golang.org/ref/spec#Integer_literals +[calls]: https://golang.org/ref/spec#Calls +[maps]: /tracks/go/concepts/maps \ No newline at end of file diff --git a/go/chessboard/README.md b/go/chessboard/README.md new file mode 100644 index 0000000..ff3e617 --- /dev/null +++ b/go/chessboard/README.md @@ -0,0 +1,187 @@ +# Chessboard + +Welcome to Chessboard on Exercism's Go 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 + +In Go, you can iterate over a `slice` using `for` and an index, or you can use `range`. +`range` also allows you to iterate over a `map`. + +Every iteration returns two values: the index/key and a copy of the element at that index/key. + +## Iterate over a slice + +Easy as pie, loops over a slice, ordered as expected. + +```go +xi := []int{10, 20, 30} +for i, x := range xi { + fmt.Println(i, x) +} +// outputs: +// 0, 10 +// 1, 20 +// 2, 30 +``` + +## Iterate over a map + +Iterating over a map raises a new problem. The order is now random. + +```go +hash := map[int]int{9: 10, 99: 20, 999: 30} +for k, v := range hash { + fmt.Println(k, v) +} +// outputs, for example: +// 99 20 +// 999 30 +// 9 10 +``` + +## Iteration omitting key or value + +In Go an unused variable will raise an error at build time. +Sometimes you only need the value, as per the first example: + +```go +xi := []int{10, 20, 30} +for i, x := range xi { + fmt.Println(x) +} +// Go build failed: i declared but not used +``` + +You can replace the `i` with `_` which tells the compiler we don't use that value: + +```go +xi := []int{10, 20, 30} +for _, x := range xi { + fmt.Println(x) +} +// outputs: +// 10 +// 20 +// 30 +``` + +If you want to only print the index, you can replace the `x` with `_`, +or simply omit the declaration: + +```go +xi := []int{10, 20, 30} +// for i, _ := range xi { +for i := range xi { + fmt.Println(i) +} +// outputs: +// 0 +// 1 +// 2 +``` + +## Non-struct types + +You've previously seen defining struct types. +It is also possible to define non-struct types which you can use as an alias for a built-in type declaration, and you can define receiver functions on them to extend them in the same way as struct types. + +```go +type Name string +func SayHello(n Name) { + fmt.Printf("Hello %s\n", n) +} +n := Name("Fred") +SayHello(n) +// Output: Hello Fred +``` + +You can also define non-struct types composed of arrays and maps. + +```go +type Names []string +func SayHello(n Names) { + for _, name := range n { + fmt.Printf("Hello %s\n", name) + } +} +n := Names([]string{"Fred", "Bill"}) +SayHello(n) +// Output: +// Hello Fred +// Hello Bill +``` + +## Instructions + +As a chess enthusiast, you would like to write your own version of the game. Yes, there may be plenty of implementations of chess available online already, but yours will be unique! + +Each square of the chessboard is identified by a letter-number pair: + - The vertical columns of squares, called files, are numbered 1 through 8. + - The horizontal rows of squares, called ranks, are labelled A through H. + +``` + 1 2 3 4 5 6 7 8 +A # _ # _ _ _ _ # A +B _ _ _ _ # _ _ _ B +C _ _ # _ _ _ _ _ C +D _ _ _ _ _ _ _ _ D +E _ _ _ _ _ # _ # E +F _ _ _ _ _ _ _ _ F +G _ _ _ # _ _ _ _ G +H # # # # # # _ # H + 1 2 3 4 5 6 7 8 +``` + +## 1. Given a Chessboard and a Rank, count how many squares are occupied + +Implement the `CountInRank(board Chessboard, rank string) int` function. +It should count the total number of occupied squares by ranging over a map. Return an integer. +Return a count of zero (`0`) if the given rank cannot be found in the map. + +```go +CountInRank(board, "A") +// => 6 +``` + +## 2. Given a Chessboard and a File, count how many squares are occupied + +Implement the `CountInFile(board Chessboard, file int) int` function. +It should count the total number of occupied squares by ranging over the given file. Return an integer. +Return a count of zero (`0`) if the given file is not a valid one (not between `1` and `8`, inclusive). + +```go +CountInFile(board, 2) +// => 5 +``` + +## 3. Count how many squares are present in the given chessboard + +Implement the `CountAll(board Chessboard) int` function. +It should count how many squares are present in the chessboard and returns +an integer. Since you don't need to check the content of the squares, +consider using range omitting both `index` and `value`. + +```go +CountAll(board) +// => 64 +``` + +## 4. Count how many squares are occupied in the given chessboard + +Implement the `CountOccupied(board Chessboard) int` function. +It should count how many squares are occupied in the chessboard. +Return an integer. + +```go +CountOccupied(board) +// => 15 +``` + +## Source + +### Created by + +- @brugnara +- @tehsphinx \ No newline at end of file diff --git a/go/chessboard/chessboard.go b/go/chessboard/chessboard.go new file mode 100644 index 0000000..19921da --- /dev/null +++ b/go/chessboard/chessboard.go @@ -0,0 +1,55 @@ +package chessboard + +// Declare a type named Rank which stores if a square is occupied by a piece - this will be a slice of bools +// Declare a type named Chessboard contains a map of eight Ranks, accessed with values from "A" to "H" +type Rank []bool +type Chessboard map[string]Rank +// CountInRank returns how many squares are occupied in the chessboard, +// within the given rank +func CountInRank(cb Chessboard, rank string) int { + sum := 0 + file, ok := cb[rank] + if !ok { + return 0 + } + for _, f := range file { + if f { + sum += 1 + } + } + return sum +} + +// CountInFile returns how many squares are occupied in the chessboard, +// within the given file +func CountInFile(cb Chessboard, file int) int { + if file < 1 || file > 8 { + return 0 + } + sum := 0 + for _, rank := range cb { + if rank[file-1] { + sum += 1 + } + } + return sum +} + +// CountAll should count how many squares are present in the chessboard +func CountAll(cb Chessboard) int { + sum := 0 + for _, rank := range cb { + sum += len(rank) + } + + return sum +} + +// CountOccupied returns how many squares are occupied in the chessboard +func CountOccupied(cb Chessboard) int { + sum := 0 + for name := range cb { + sum += CountInRank(cb, name) + } + return sum +} diff --git a/go/chessboard/chessboard_test.go b/go/chessboard/chessboard_test.go new file mode 100644 index 0000000..7c73b79 --- /dev/null +++ b/go/chessboard/chessboard_test.go @@ -0,0 +1,100 @@ +package chessboard + +import ( + "testing" +) + +// newChessboard return a *Chessboard for tests +// +// 1 2 3 4 5 6 7 8 +// A # _ # _ _ _ _ # A +// B _ _ _ _ # _ _ _ B +// C _ _ # _ _ _ _ _ C +// D _ _ _ _ _ _ _ _ D +// E _ _ _ _ _ # _ # E +// F _ _ _ _ _ _ _ _ F +// G _ _ _ # _ _ _ _ G +// H # # # # # # _ # H +// 1 2 3 4 5 6 7 8 +func newChessboard() Chessboard { + return Chessboard{ + "A": Rank{true, false, true, false, false, false, false, true}, + "B": Rank{false, false, false, false, true, false, false, false}, + "C": Rank{false, false, true, false, false, false, false, false}, + "D": Rank{false, false, false, false, false, false, false, false}, + "E": Rank{false, false, false, false, false, true, false, true}, + "F": Rank{false, false, false, false, false, false, false, false}, + "G": Rank{false, false, false, true, false, false, false, false}, + "H": Rank{true, true, true, true, true, true, false, true}, + } +} + +func TestCountInRank(t *testing.T) { + cb := newChessboard() + for _, test := range []struct { + in string + out int + }{ + {"A", 3}, + {"B", 1}, + {"C", 1}, + {"D", 0}, + {"E", 2}, + {"F", 0}, + {"G", 1}, + {"H", 7}, + {"Z", 0}, + } { + if out := CountInRank(cb, test.in); out != test.out { + t.Errorf( + "CountInRank(chessboard, '%v') returned %v while %v was expected\n", + test.in, + out, + test.out, + ) + } + } +} + +func TestCountInFile(t *testing.T) { + cb := newChessboard() + for _, test := range []struct { + in int + out int + }{ + {1, 2}, + {2, 1}, + {3, 3}, + {4, 2}, + {5, 2}, + {6, 2}, + {7, 0}, + {8, 3}, + {100, 0}, + } { + if out := CountInFile(cb, test.in); out != test.out { + t.Errorf( + "CountInFile(chessboard, %v) returned %v while %v was expected\n", + test.in, + out, + test.out, + ) + } + } +} + +func TestCountAll(t *testing.T) { + cb := newChessboard() + wanted := 64 + if out := CountAll(cb); out != wanted { + t.Errorf("CountAll(chessboard) returned %v while %v was expected", out, wanted) + } +} + +func TestCountOccupied(t *testing.T) { + cb := newChessboard() + wanted := 15 + if out := CountOccupied(cb); out != wanted { + t.Errorf("CountOccupied(chessboard) returned %v while %v was expected", out, wanted) + } +} diff --git a/go/chessboard/go.mod b/go/chessboard/go.mod new file mode 100644 index 0000000..d796396 --- /dev/null +++ b/go/chessboard/go.mod @@ -0,0 +1,3 @@ +module chessboard + +go 1.16 diff --git a/go/election-day/.exercism/config.json b/go/election-day/.exercism/config.json new file mode 100644 index 0000000..f936be5 --- /dev/null +++ b/go/election-day/.exercism/config.json @@ -0,0 +1,21 @@ +{ + "blurb": "Learn about pointers by creating a simple voting system.", + "authors": [ + "andrerfcsantos" + ], + "contributors": [], + "files": { + "solution": [ + "election_day.go" + ], + "test": [ + "election_day_test.go" + ], + "exemplar": [ + ".meta/exemplar.go" + ], + "editor": [ + "election_result.go" + ] + } +} diff --git a/go/election-day/.exercism/metadata.json b/go/election-day/.exercism/metadata.json new file mode 100644 index 0000000..c735cb0 --- /dev/null +++ b/go/election-day/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"election-day","id":"66656b96ab674bcca386330eb9bff31c","url":"https://exercism.org/tracks/go/exercises/election-day","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/go/election-day/HELP.md b/go/election-day/HELP.md new file mode 100644 index 0000000..b16ca2a --- /dev/null +++ b/go/election-day/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit election_day.go` 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 [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/go/election-day/HINTS.md b/go/election-day/HINTS.md new file mode 100644 index 0000000..c666c18 --- /dev/null +++ b/go/election-day/HINTS.md @@ -0,0 +1,54 @@ +# Hints + +## General + +- `*T` can be used to declared variables that are pointers to some type `T`, e.g `var i *int` declares a variable `i` that is a pointer to an `int` +- You can get a pointer for a variable (its memory address) by using the `&` operator, e.g `mypointer := &anIntVariable`. +- You can get the value stored in a pointer by using the `*` operator on a pointer, eg. `var i int = *aPointerToInt`. This is called dereferencing the pointer. +- You check if a pointer is not `nil` before dereferencing it. Attempting to dereference a `nil` pointer will give you a runtime error. +- If you are unsure how pointers work, try reading [Tour of Go: Pointers][go-tour-pointers] or [Go by Example: Pointers][go-by-example-pointers] + +## 1. Create a vote counter + +- You need to create a pointer to an `int`, in other words, a `*int`. +- You can use the `&` operator on a variable to create a pointer to it, e.g `&myInt` +- You can create a pointer to a new variable defined by you or you can use the variable of the function argument + +## 2. Get number of votes from a counter + +- You can use the `*` operator on a pointer to dereference it and get its value, e.g `*myPointer` +- Dereferencing `nil` pointers will give you a runtime error. Always make sure a pointer is not `nil` before dereferencing it. + +## 3. Increment the votes of a counter + +- If you have a pointer `var myPointer *int`, you can assign to `*myPointer` to change the value pointed by `myPointer` +- To get the current value of the pointer, you need to dereference it using the `*` operator, or call the function you made in the previous task. + +## 4. Create the election results + +- Create a new `ElectionResult` literal or variable with the fields `Name` and `Votes` filled with the values in the arguments of the function. +- You can create a pointer from a variable or literal by using the `&` operator before the variable name/literal declaration, e.g `&myVariable` or `&ElectionResult{Name: "John", Votes: 1}` + +## 5. Announce the results + +- Although you are receiving a pointer to an `ElectionResult`, you can access its fields with the dot `.` notation, like if it wasn't a pointer! +- Build the message by accessing the `Name` and `Value` fields on the struct. +- Even though you are accessing fields from a pointer to a struct, you don't need to do any dereferencing. Go will automatically dereference the pointer for you, like in this example: + +```go +result := &ElectionResult{ + Name: "John", + Votes: 32 +} + +result.Name // "John" - Go will automatically dereference the pointer + // and access the 'Name' field of the dereferenced struct +``` + +## 6. Vote recounting + +- You can think of maps as being pointers already. This means that changes you make to the map inside the function will be visible outside the function. +- To increment the value of a key in a `var m map[string]int`, you have several options: `m["mykey"] = m["mykey"] + 1 `, `m["mykey"] += 1 ` or `m["mykey"]++ ` + +[go-tour-pointers]: https://tour.golang.org/moretypes/1 +[go-by-example-pointers]: https://gobyexample.com/pointers \ No newline at end of file diff --git a/go/election-day/README.md b/go/election-day/README.md new file mode 100644 index 0000000..7125a31 --- /dev/null +++ b/go/election-day/README.md @@ -0,0 +1,301 @@ +# Election Day + +Welcome to Election Day on Exercism's Go 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 + +Like many other languages, Go has pointers. +If you're new to pointers, they can feel a little mysterious but once you get used to them, they're quite straight-forward. +They're a crucial part of Go, so take some time to really understand them. + +Before digging into the details, it's worth understanding the use of pointers. Pointers are a way to share memory with other parts of our program, which is useful for two major reasons: +1. When we have large amounts of data, making copies to pass between functions is very inefficient. + By passing the memory location of where the data is stored instead, we can dramatically reduce the resource-footprint of our programs. +2. By passing pointers between functions, we can access and modify the single copy of the data directly, meaning that any changes made by one function are immediately visible to other parts of the program when the function ends. + +## Variables and Memory + +Let's say we have a regular integer variable `a`: + +```go +var a int +``` + +When we declare a variable, Go has to find a place in memory to store its value. This is largely abstracted from us — when we need to fetch the value stored in that piece of memory, we can just refer to it by the variable name. + +For instance, when we write `a + 2`, we are effectively fetching the value stored in the memory associated with the variable `a` and adding 2 to it. + +Similarly, when we need to change the value in the piece of memory of `a`, we can use the variable name to do an assignment: + +```go +a = 3 +``` + +The piece of memory that is associated with `a` will now be storing the value `3`. + +## Pointers + +While variables allow us to refer to values in memory, sometimes it's useful to know the **memory address** to which the variable is pointing. **Pointers** hold the memory addresses of those values. You declare a variable with a pointer type by prefixing the underlying type with an asterisk: + +```go +var p *int // 'p' contains the memory address of an integer +``` + +Here we declare a variable `p` of type "pointer to int" (`*int`). This means that `p` will hold the memory address of an integer. The zero value of pointers is `nil` because a `nil` pointer holds no memory address. + +### Getting a pointer to a variable + +To find the memory address of the value of a variable, we can use the `&` operator. +For example, if we want to find and store the memory address of variable `a` in the pointer `p`, we can do the following: + +```go +var a int +a = 2 + +var p *int +p = &a // the variable 'p' contains the memory address of 'a' +``` + +### Accessing the value via a pointer (dereferencing) + +When we have a pointer, we might want to know the value stored in the memory address the pointer represents. We can do this using the `*` operator: + +```go +var a int +a = 2 + +var p *int +p = &a // the variable 'p' contains the memory address of 'a' + +var b int +b = *p // b == 2 +``` + +The operation `*p` fetches the value stored at the memory address stored in `p`. This operation is often called "dereferencing". + +We can also use the dereference operator to assign a new value to the memory address referenced by the pointer: + +```go +var a int +a = 2 // declare int variable 'a' and assign it the value of 2 + +var pa *int +pa = &a // 'pa' now contains to the memory address of 'a' +*pa = *pa + 2 // increment by 2 the value at memory address 'pa' + +fmt.Println(a) // Output: 4 + // 'a' will have the new value that was changed via the pointer! +``` + +Assigning to `*pa` will change the value stored at the memory address `pa` holds. Since `pa` holds the memory address of `a`, by assigning to `*pa` we are effectively changing the value of `a`! + +A note of caution however: always check if a pointer is not `nil` before dereferencing. Dereferencing a `nil` pointer will make the program crash at runtime! + +```go +var p *int // p is nil initially +fmt.Println(*p) +// panic: runtime error: invalid memory address or nil pointer dereference +``` + +### Pointers to structs + +So far we've only seen pointers to primitive values. We can also create pointers for structs: + +```go +type Person struct { + Name string + Age int +} + +var peter Person +peter = Person{Name: "Peter", Age: 22} + +var p *Person +p = &peter +``` + +We could have also created a new `Person` and immediately stored a pointer to it: + +```go +var p *Person +p = &Person{Name: "Peter", Age: 22} +``` + +When we have a pointer to a struct, we don't need to dereference the pointer before accessing one of the fields: + +```go +var p *Person +p = &Person{Name: "Peter", Age: 22} + +fmt.Println(p.Name) // Output: "Peter" + // Go automatically dereferences 'p' to allow + // access to the 'Name' field +``` + +## Slices and maps are already pointers + +Slices and maps are special types because they already have pointers in their implementation. This means that more often that not, we don't need to create pointers for these types to share the memory address for their values. Imagine we have a function that increments the value of a key in a map: + + +```go +func incrementPeterAge(m map[string]int) { + m["Peter"] += 1 +} +``` + +If we create a map and call this function, the changes the function made to the map persist after the function ended. This is a similar behavior we get if we were using a pointer, but note how on this example we are not using any referencing/dereferencing or any of the pointer syntax: + +```go +ages := map[string]int{ + "Peter": 21 +} +incrementPeterAge(ages) +fmt.Println(ages) +// Output: map[Peter:22] +// The changes the function 'addPeterAge' made to the map are visible after the function ends! +``` + +The same applies when changing an existing item in a slice. + +However, actions that return a new slice like `append` are a special case and **might not** modify the slice outside of the function. This is due to the way slices work internally, but we won't cover this in detail in this exercise, as this is a more advanced topic. If you are really curious you can read more about this in [Go Blog: Mechanics of 'append'][mechanics-of-append] + +[mechanics-of-append]: https://go.dev/blog/slices + +## Instructions + +A local school near you has a very active students' association. +The students' association is managed by a president and once every 2 years, +elections are run to elect a new president. + +In this year's election, it was decided that a new digital system to +count the votes was needed. The school needs your help building this new system. + +## 1. Create a vote counter + +One of the first things that the new voting system needs is a vote counter. +This counter is a way to keep track of the votes a particular candidate has. + +Create a function `NewVoteCounter` that accepts the number of initial votes for a candidate and returns a pointer referring to an `int`, initialized with the given number of initial votes. + +```go +var initialVotes int +initialVotes = 2 + +var counter *int +counter = NewVoteCounter(initialVotes) +*counter == initialVotes // true +``` + +## 2. Get number of votes from a counter + +You now have a way to create new counters! But now you realize the new system will also need a way to get the number of votes from a counter. + +Create a function `VoteCount` that will take a counter (`*int`) as an argument and will return the number of votes in the counter. If the counter is `nil` you should assume the counter has no votes: + +```go +var votes int +votes = 3 + +var voteCounter *int +voteCounter = &votes + +VoteCount(voteCounter) +// Output: 3 + +var nilVoteCounter *int +VoteCount(nilVoteCounter) +// Output: 0 +``` + +## 3. Increment the votes of a counter + +It's finally the time to count the votes! Now you need a way to increment the votes in a counter. + +Create a function `IncrementVoteCount` that will take a counter (`*int`) as an argument and a number of votes, and will increment the counter by that number of votes. You can assume the pointer passed will never be `nil`. + +```go +var votes int +votes = 3 + +var voteCounter *int +voteCounter = &votes + +IncrementVoteCount(voteCounter, 2) + +votes == 5 // true +*voteCounter == 5 // true +``` + +## 4. Create the election results + +With all the votes now counted, it's time to prepare the result announcement to the whole school. +For this, you notice that having only counters for the votes is insufficient. +There needs to be a way to associate the number of votes with a particular candidate. + +Create a function `NewElectionResult` that receives the name of a candidate and their number of votes and +returns a new election result. + +```go +var result *ElectionResult +result = NewElectionResult("Peter", 3) + +result.Name == "Peter" // true +result.Votes == 3 // true +``` + +The election result struct is already created for you and it's defined as: + +```go +type ElectionResult struct { + // Name of the candidate + Name string + // Number of votes the candidate had + Votes int +} +``` + +## 5. Announce the results + +It's time to announce the new president to the school! +The president will be announced in the little digital message boards that the school has. +The message should show the name of the new president and the votes it had, in the following format: ` ()`. This is an example of such message: `"Peter (51)"`. + +Create a function `DisplayResult` that will receive an `*ElectionResult` as an argument and will return a string with the message to display. + + +```go +var result *ElectionResult +result = &ElectionResult{ + Name: "John", + Votes: 32, +} + +DisplayResult(result) +// Output: John (32) +``` + +## 6. Vote recounting + +To make sure the final results were accurate, the votes were recounted. In the recount, it was found that the number votes for some of the candidates was off by one. + +Create a function `DecrementVotesOfCandidate` that receives the final results and the name of a candidate for which you should decrement its vote count. The final results are given in the form of a `map[string]int`, where the keys are the names of the candidates and the values are its total votes. + +```go +var finalResults = map[string]int{ + "Mary": 10, + "John": 51, +} + +DecrementVotesOfCandidate(finalResults, "Mary") + +finalResults["Mary"] +// Output: 9 +``` + +## Source + +### Created by + +- @andrerfcsantos \ No newline at end of file diff --git a/go/election-day/election_day.go b/go/election-day/election_day.go new file mode 100644 index 0000000..c762e8b --- /dev/null +++ b/go/election-day/election_day.go @@ -0,0 +1,32 @@ +package electionday + +// NewVoteCounter returns a new vote counter with +// a given number of inital votes. +func NewVoteCounter(initialVotes int) *int { + panic("Please implement the NewVoteCounter() function") +} + +// VoteCount extracts the number of votes from a counter. +func VoteCount(counter *int) int { + panic("Please implement the VoteCount() function") +} + +// IncrementVoteCount increments the value in a vote counter +func IncrementVoteCount(counter *int, increment int) { + panic("Please implement the IncrementVoteCount() function") +} + +// NewElectionResult creates a new election result +func NewElectionResult(candidateName string, votes int) *ElectionResult { + panic("Please implement the NewElectionResult() function") +} + +// DisplayResult creates a message with the result to be displayed +func DisplayResult(result *ElectionResult) string { + panic("Please implement the DisplayResult() function") +} + +// DecrementVotesOfCandidate decrements by one the vote count of a candidate in a map +func DecrementVotesOfCandidate(results map[string]int, candidate string) { + panic("Please implement the DecrementVotesOfCandidate() function") +} diff --git a/go/election-day/election_day_test.go b/go/election-day/election_day_test.go new file mode 100644 index 0000000..ad1512f --- /dev/null +++ b/go/election-day/election_day_test.go @@ -0,0 +1,183 @@ +package electionday + +import ( + "strconv" + "testing" +) + +func TestNewVoteCounter(t *testing.T) { + tests := []struct { + name string + votes int + }{ + { + name: "Simple vote counter with 2 votes", + votes: 2, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := NewVoteCounter(tt.votes) + if got == nil { + t.Errorf("NewVoteCounter(%d) = %s, &%d", tt.votes, intPtrRepresentation(got), tt.votes) + } + if got != nil && *got != tt.votes { + t.Errorf("NewVoteCounter(%d) = %s, &%d", tt.votes, intPtrRepresentation(got), tt.votes) + } + }) + } +} + +func TestVoteCount(t *testing.T) { + twoVotes := 2 + + tests := []struct { + name string + counter *int + expected int + }{ + { + name: "Call to VoteCount with a nil argument", + counter: nil, + expected: 0, + }, + { + name: "Call to VoteCount with a pointer to an int with a value of 2", + counter: &twoVotes, + expected: 2, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := VoteCount(tt.counter); got != tt.expected { + t.Fatalf("VoteCount(%v) = %d, want %d", intPtrRepresentation(tt.counter), got, tt.expected) + } + }) + } +} + +func TestIncrementVoteCount(t *testing.T) { + twoVotes := 2 + + tests := []struct { + name string + counter *int + increment int + expected int + }{ + { + name: "Call to IncrementVoteCount with a pointer to an int with a value of 2 and increment of 2", + counter: &twoVotes, + increment: 2, + expected: 4, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + before := intPtrRepresentation(tt.counter) + IncrementVoteCount(tt.counter, tt.increment) + after := intPtrRepresentation(tt.counter) + + if tt.counter == nil { + t.Errorf("counter before: %s | counter after: %v | wanted: &%d", before, after, tt.expected) + } + + if tt.counter != nil && *tt.counter != tt.expected { + t.Errorf("counter before: %s | counter after: %v | wanted: &%d", before, after, tt.expected) + } + }) + } +} + +func TestNewElectionResult(t *testing.T) { + tests := []struct { + name string + candidateName string + votes int + wanted ElectionResult + }{ + { + name: "Call to NewElectionResult for Peter with 2 votes", + candidateName: "Peter", + votes: 2, + wanted: ElectionResult{ + Name: "Peter", + Votes: 2, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := NewElectionResult(tt.candidateName, tt.votes) + + if result == nil || result.Name != tt.wanted.Name || result.Votes != tt.wanted.Votes { + t.Errorf("NewElectionResult(\"%s\", %d) = %#v, wanted %#v", + tt.candidateName, tt.votes, result, tt.wanted) + } + }) + } +} + +func TestDisplayResult(t *testing.T) { + tests := []struct { + name string + result *ElectionResult + wanted string + }{ + { + name: "Call to DisplayResult for Jonh with 5 votes", + result: &ElectionResult{ + Name: "John", + Votes: 5, + }, + wanted: "John (5)", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if result := DisplayResult(tt.result); result != tt.wanted { + t.Errorf("DisplayResult(%#v) = %s, wanted %s", *tt.result, result, tt.wanted) + } + }) + } +} + +func TestDecrementVotesOfCandidate(t *testing.T) { + tests := []struct { + name string + candidate string + results map[string]int + wanted int + }{ + { + name: "Call to DecrementVotesOfCandidate for Jonh with 5 votes", + candidate: "John", + results: map[string]int{ + "John": 3, + }, + wanted: 2, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + DecrementVotesOfCandidate(tt.results, tt.candidate) + if votes, ok := tt.results[tt.candidate]; !ok || votes != tt.wanted { + t.Errorf("DecrementVotesOfCandidate(%v) | wanted %d, got %d", + tt.results, tt.wanted, votes) + } + }) + } +} + +func intPtrRepresentation(p *int) string { + if p == nil { + return "nil" + } + return "&" + strconv.Itoa(*p) +} diff --git a/go/election-day/election_result.go b/go/election-day/election_result.go new file mode 100644 index 0000000..a6491fe --- /dev/null +++ b/go/election-day/election_result.go @@ -0,0 +1,9 @@ +package electionday + +// ElectionResult represents an election result +type ElectionResult struct { + // Name of the candidate + Name string + // Number of votes the candidate had + Votes int +} diff --git a/go/election-day/go.mod b/go/election-day/go.mod new file mode 100644 index 0000000..897a8b2 --- /dev/null +++ b/go/election-day/go.mod @@ -0,0 +1,3 @@ +module electionday + +go 1.16 diff --git a/go/forth/.exercism/config.json b/go/forth/.exercism/config.json new file mode 100644 index 0000000..f47158e --- /dev/null +++ b/go/forth/.exercism/config.json @@ -0,0 +1,31 @@ +{ + "blurb": "Implement an evaluator for a very simple subset of Forth", + "authors": [ + "leenipper" + ], + "contributors": [ + "alebaffa", + "bitfield", + "da-edra", + "ekingery", + "ferhatelmas", + "hilary", + "ilmanzo", + "robphoenix", + "sebito91" + ], + "files": { + "solution": [ + "forth.go" + ], + "test": [ + "forth_test.go" + ], + "example": [ + ".meta/example.go" + ], + "editor": [ + "cases_test.go" + ] + } +} diff --git a/go/forth/.exercism/metadata.json b/go/forth/.exercism/metadata.json new file mode 100644 index 0000000..def2159 --- /dev/null +++ b/go/forth/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"forth","id":"7fb99fd3f78d43c6a59dd057cac693da","url":"https://exercism.org/tracks/go/exercises/forth","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/go/forth/HELP.md b/go/forth/HELP.md new file mode 100644 index 0000000..79f04c4 --- /dev/null +++ b/go/forth/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit forth.go` 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 [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/go/forth/README.md b/go/forth/README.md new file mode 100644 index 0000000..1795ee6 --- /dev/null +++ b/go/forth/README.md @@ -0,0 +1,49 @@ +# Forth + +Welcome to Forth on Exercism's Go Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +Implement an evaluator for a very simple subset of Forth. + +[Forth](https://en.wikipedia.org/wiki/Forth_%28programming_language%29) +is a stack-based programming language. Implement a very basic evaluator +for a small subset of Forth. + +Your evaluator has to support the following words: + +- `+`, `-`, `*`, `/` (integer arithmetic) +- `DUP`, `DROP`, `SWAP`, `OVER` (stack manipulation) + +Your evaluator also has to support defining new words using the +customary syntax: `: word-name definition ;`. + +To keep things simple the only data type you need to support is signed +integers of at least 16 bits size. + +You should use the following rules for the syntax: a number is a +sequence of one or more (ASCII) digits, a word is a sequence of one or +more letters, digits, symbols or punctuation that is not a number. +(Forth probably uses slightly different rules, but this is close +enough.) + +Words are case-insensitive. + +## Source + +### Created by + +- @leenipper + +### Contributed to by + +- @alebaffa +- @bitfield +- @da-edra +- @ekingery +- @ferhatelmas +- @hilary +- @ilmanzo +- @robphoenix +- @sebito91 \ No newline at end of file diff --git a/go/forth/cases_test.go b/go/forth/cases_test.go new file mode 100644 index 0000000..735089a --- /dev/null +++ b/go/forth/cases_test.go @@ -0,0 +1,309 @@ +package forth + +// Source: exercism/problem-specifications +// Commit: 75f4c0a Corrected minor typos in the error msg expectation (doesn't match other similar error patterns and so breaks auto generated tests) +// Problem Specifications Version: 1.7.1 + +type testGroup struct { + group string + tests []testCase +} + +type testCase struct { + description string + input []string + expected []int // nil slice indicates error expected. +} + +var testGroups = []testGroup{ + { + group: "parsing and numbers", + tests: []testCase{ + { + "numbers just get pushed onto the stack", + []string{"1 2 3 4 5"}, + []int{1, 2, 3, 4, 5}, + }, + }, + }, + { + group: "addition", + tests: []testCase{ + { + "can add two numbers", + []string{"1 2 +"}, + []int{3}, + }, + { + "errors if there is nothing on the stack", + []string{"+"}, + []int(nil), + }, + { + "errors if there is only one value on the stack", + []string{"1 +"}, + []int(nil), + }, + }, + }, + { + group: "subtraction", + tests: []testCase{ + { + "can subtract two numbers", + []string{"3 4 -"}, + []int{-1}, + }, + { + "errors if there is nothing on the stack", + []string{"-"}, + []int(nil), + }, + { + "errors if there is only one value on the stack", + []string{"1 -"}, + []int(nil), + }, + }, + }, + { + group: "multiplication", + tests: []testCase{ + { + "can multiply two numbers", + []string{"2 4 *"}, + []int{8}, + }, + { + "errors if there is nothing on the stack", + []string{"*"}, + []int(nil), + }, + { + "errors if there is only one value on the stack", + []string{"1 *"}, + []int(nil), + }, + }, + }, + { + group: "division", + tests: []testCase{ + { + "can divide two numbers", + []string{"12 3 /"}, + []int{4}, + }, + { + "performs integer division", + []string{"8 3 /"}, + []int{2}, + }, + { + "errors if dividing by zero", + []string{"4 0 /"}, + []int(nil), + }, + { + "errors if there is nothing on the stack", + []string{"/"}, + []int(nil), + }, + { + "errors if there is only one value on the stack", + []string{"1 /"}, + []int(nil), + }, + }, + }, + { + group: "combined arithmetic", + tests: []testCase{ + { + "addition and subtraction", + []string{"1 2 + 4 -"}, + []int{-1}, + }, + { + "multiplication and division", + []string{"2 4 * 3 /"}, + []int{2}, + }, + }, + }, + { + group: "dup", + tests: []testCase{ + { + "copies a value on the stack", + []string{"1 dup"}, + []int{1, 1}, + }, + { + "copies the top value on the stack", + []string{"1 2 dup"}, + []int{1, 2, 2}, + }, + { + "errors if there is nothing on the stack", + []string{"dup"}, + []int(nil), + }, + }, + }, + { + group: "drop", + tests: []testCase{ + { + "removes the top value on the stack if it is the only one", + []string{"1 drop"}, + []int{}, + }, + { + "removes the top value on the stack if it is not the only one", + []string{"1 2 drop"}, + []int{1}, + }, + { + "errors if there is nothing on the stack", + []string{"drop"}, + []int(nil), + }, + }, + }, + { + group: "swap", + tests: []testCase{ + { + "swaps the top two values on the stack if they are the only ones", + []string{"1 2 swap"}, + []int{2, 1}, + }, + { + "swaps the top two values on the stack if they are not the only ones", + []string{"1 2 3 swap"}, + []int{1, 3, 2}, + }, + { + "errors if there is nothing on the stack", + []string{"swap"}, + []int(nil), + }, + { + "errors if there is only one value on the stack", + []string{"1 swap"}, + []int(nil), + }, + }, + }, + { + group: "over", + tests: []testCase{ + { + "copies the second element if there are only two", + []string{"1 2 over"}, + []int{1, 2, 1}, + }, + { + "copies the second element if there are more than two", + []string{"1 2 3 over"}, + []int{1, 2, 3, 2}, + }, + { + "errors if there is nothing on the stack", + []string{"over"}, + []int(nil), + }, + { + "errors if there is only one value on the stack", + []string{"1 over"}, + []int(nil), + }, + }, + }, + { + group: "user-defined words", + tests: []testCase{ + { + "can consist of built-in words", + []string{": dup-twice dup dup ;", "1 dup-twice"}, + []int{1, 1, 1}, + }, + { + "execute in the right order", + []string{": countup 1 2 3 ;", "countup"}, + []int{1, 2, 3}, + }, + { + "can override other user-defined words", + []string{": foo dup ;", ": foo dup dup ;", "1 foo"}, + []int{1, 1, 1}, + }, + { + "can override built-in words", + []string{": swap dup ;", "1 swap"}, + []int{1, 1}, + }, + { + "can override built-in operators", + []string{": + * ;", "3 4 +"}, + []int{12}, + }, + { + "can use different words with the same name", + []string{": foo 5 ;", ": bar foo ;", ": foo 6 ;", "bar foo"}, + []int{5, 6}, + }, + { + "can define word that uses word with the same name", + []string{": foo 10 ;", ": foo foo 1 + ;", "foo"}, + []int{11}, + }, + { + "cannot redefine numbers", + []string{": 1 2 ;"}, + []int(nil), + }, + { + "errors if executing a non-existent word", + []string{"foo"}, + []int(nil), + }, + }, + }, + { + group: "case-insensitivity", + tests: []testCase{ + { + "DUP is case-insensitive", + []string{"1 DUP Dup dup"}, + []int{1, 1, 1, 1}, + }, + { + "DROP is case-insensitive", + []string{"1 2 3 4 DROP Drop drop"}, + []int{1}, + }, + { + "SWAP is case-insensitive", + []string{"1 2 SWAP 3 Swap 4 swap"}, + []int{2, 3, 4, 1}, + }, + { + "OVER is case-insensitive", + []string{"1 2 OVER Over over"}, + []int{1, 2, 1, 2, 1}, + }, + { + "user-defined words are case-insensitive", + []string{": foo dup ;", "1 FOO Foo foo"}, + []int{1, 1, 1, 1}, + }, + { + "definitions are case-insensitive", + []string{": SWAP DUP Dup dup ;", "1 swap"}, + []int{1, 1, 1, 1}, + }, + }, + }, +} diff --git a/go/forth/forth.go b/go/forth/forth.go new file mode 100644 index 0000000..2b457e6 --- /dev/null +++ b/go/forth/forth.go @@ -0,0 +1,5 @@ +package forth + +func Forth(input []string) ([]int, error) { + panic("Please implement the Forth function") +} diff --git a/go/forth/forth_test.go b/go/forth/forth_test.go new file mode 100644 index 0000000..3a5fb73 --- /dev/null +++ b/go/forth/forth_test.go @@ -0,0 +1,40 @@ +package forth + +import ( + "reflect" + "testing" +) + +func TestForth(t *testing.T) { + for _, tg := range testGroups { + for _, tc := range tg.tests { + if v, err := Forth(tc.input); err == nil { + var _ error = err + if tc.expected == nil { + t.Fatalf("FAIL: %s | %s\n\tForth(%#v) expected an error, got %v", + tg.group, tc.description, tc.input, v) + } else if !reflect.DeepEqual(v, tc.expected) { + t.Fatalf("FAIL: %s | %s\n\tForth(%#v) expected %v, got %v", + tg.group, tc.description, tc.input, tc.expected, v) + } + } else if tc.expected != nil { + t.Fatalf("FAIL: %s | %s\n\tForth(%#v) expected %v, got an error: %q", + tg.group, tc.description, tc.input, tc.expected, err) + } + t.Logf("PASS: %s | %s", tg.group, tc.description) + } + } +} + +func BenchmarkForth(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + for i := 0; i < b.N; i++ { + for _, tg := range testGroups { + for _, tc := range tg.tests { + Forth(tc.input) + } + } + } +} diff --git a/go/forth/go.mod b/go/forth/go.mod new file mode 100644 index 0000000..86cb142 --- /dev/null +++ b/go/forth/go.mod @@ -0,0 +1,3 @@ +module forth + +go 1.16 diff --git a/go/forth/stack.go b/go/forth/stack.go new file mode 100644 index 0000000..d9ff3c2 --- /dev/null +++ b/go/forth/stack.go @@ -0,0 +1,24 @@ +package forth + +import "fmt" + + + +type Stack struct { + stack []int + ptr int +} + +func (s *Stack) Push(k int) { + s.stack = append(s.stack, k) +} + +func (s *Stack) Pop() (int, error) { + if len(s.stack) == 0 { + return 0, fmt.Errorf("cannot pop empty stack") + } + + el := s.stack[len(s.stack)-1] + s.stack = s.stack[:len(s.stack)-1] + return el, nil +} diff --git a/go/grains/.exercism/config.json b/go/grains/.exercism/config.json new file mode 100644 index 0000000..b81e706 --- /dev/null +++ b/go/grains/.exercism/config.json @@ -0,0 +1,40 @@ +{ + "blurb": "Calculate the number of grains of wheat on a chessboard given that the number on each square doubles.", + "authors": [ + "nathany" + ], + "contributors": [ + "alebaffa", + "bitfield", + "da-edra", + "dvrkps", + "ekingery", + "ferhatelmas", + "hilary", + "ilmanzo", + "johngb", + "kytrinyx", + "leenipper", + "petertseng", + "robphoenix", + "sebito91", + "strangeman", + "tleen" + ], + "files": { + "solution": [ + "grains.go" + ], + "test": [ + "grains_test.go" + ], + "example": [ + ".meta/example.go" + ], + "editor": [ + "cases_test.go" + ] + }, + "source": "JavaRanch Cattle Drive, exercise 6", + "source_url": "http://www.javaranch.com/grains.jsp" +} diff --git a/go/grains/.exercism/metadata.json b/go/grains/.exercism/metadata.json new file mode 100644 index 0000000..c24df4e --- /dev/null +++ b/go/grains/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"grains","id":"4d2b822b76a64e4790a85240381853a7","url":"https://exercism.org/tracks/go/exercises/grains","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/go/grains/HELP.md b/go/grains/HELP.md new file mode 100644 index 0000000..ecd48e4 --- /dev/null +++ b/go/grains/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit grains.go` 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 [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/go/grains/README.md b/go/grains/README.md new file mode 100644 index 0000000..bf22896 --- /dev/null +++ b/go/grains/README.md @@ -0,0 +1,62 @@ +# Grains + +Welcome to Grains on Exercism's Go Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +Calculate the number of grains of wheat on a chessboard given that the number +on each square doubles. + +There once was a wise servant who saved the life of a prince. The king +promised to pay whatever the servant could dream up. Knowing that the +king loved chess, the servant told the king he would like to have grains +of wheat. One grain on the first square of a chess board, with the number +of grains doubling on each successive square. + +There are 64 squares on a chessboard (where square 1 has one grain, square 2 has two grains, and so on). + +Write code that shows: + +- how many grains were on a given square, and +- the total number of grains on the chessboard + +## For bonus points + +Did you get the tests passing and the code clean? If you want to, these +are some additional things you could try: + +- Optimize for speed. +- Optimize for readability. + +Then please share your thoughts in a comment on the submission. Did this +experiment make the code better? Worse? Did you learn anything from it? + +## Source + +### Created by + +- @nathany + +### Contributed to by + +- @alebaffa +- @bitfield +- @da-edra +- @dvrkps +- @ekingery +- @ferhatelmas +- @hilary +- @ilmanzo +- @johngb +- @kytrinyx +- @leenipper +- @petertseng +- @robphoenix +- @sebito91 +- @strangeman +- @tleen + +### Based on + +JavaRanch Cattle Drive, exercise 6 - http://www.javaranch.com/grains.jsp \ No newline at end of file diff --git a/go/grains/cases_test.go b/go/grains/cases_test.go new file mode 100644 index 0000000..4185710 --- /dev/null +++ b/go/grains/cases_test.go @@ -0,0 +1,64 @@ +package grains + +// Source: exercism/problem-specifications +// Commit: 2ec42ab Grains: Fixed canonical data to have standard error indicator (#1322) +// Problem Specifications Version: 1.2.0 + +// returns the number of grains on the square +var squareTests = []struct { + description string + input int + expectedVal uint64 + expectError bool +}{ + { + description: "1", + input: 1, + expectedVal: 1, + }, + { + description: "2", + input: 2, + expectedVal: 2, + }, + { + description: "3", + input: 3, + expectedVal: 4, + }, + { + description: "4", + input: 4, + expectedVal: 8, + }, + { + description: "16", + input: 16, + expectedVal: 32768, + }, + { + description: "32", + input: 32, + expectedVal: 2147483648, + }, + { + description: "64", + input: 64, + expectedVal: 9223372036854775808, + }, + { + description: "square 0 returns an error", + input: 0, + expectError: true, + }, + { + description: "negative square returns an error", + input: -1, + expectError: true, + }, + { + description: "square greater than 64 returns an error", + input: 65, + expectError: true, + }, +} diff --git a/go/grains/go.mod b/go/grains/go.mod new file mode 100644 index 0000000..c47cb7f --- /dev/null +++ b/go/grains/go.mod @@ -0,0 +1,3 @@ +module grains + +go 1.13 diff --git a/go/grains/grains.go b/go/grains/grains.go new file mode 100644 index 0000000..32dae1c --- /dev/null +++ b/go/grains/grains.go @@ -0,0 +1,16 @@ +package grains + +import ( + "fmt" +) + +func Square(number int) (uint64, error) { + if number < 1 || number > 64 { + return 0, fmt.Errorf("bad square %d (must be between 1-64)", number) + } + return 1<<(number - 1), nil +} + +func Total() uint64 { + return 1<<64 - 1 +} diff --git a/go/grains/grains_test.go b/go/grains/grains_test.go new file mode 100644 index 0000000..de031e1 --- /dev/null +++ b/go/grains/grains_test.go @@ -0,0 +1,57 @@ +package grains + +import ( + "testing" +) + +func TestSquare(t *testing.T) { + for _, test := range squareTests { + actualVal, actualErr := Square(test.input) + + // check actualVal only if no error expected + if !test.expectError && actualVal != test.expectedVal { + t.Fatalf("FAIL: %s\nSquare(%d) expected %d, Actual %d", test.description, test.input, test.expectedVal, actualVal) + } + + // if we expect an error and there isn't one + if test.expectError && actualErr == nil { + t.Fatalf("FAIL: %s\nSquare(%d) expected an error, but error is nil", test.description, test.input) + } + // if we don't expect an error and there is one + if !test.expectError && actualErr != nil { + var _ error = actualErr + t.Fatalf("FAIL: %s\nSquare(%d) expected no error, but error is: %s", test.description, test.input, actualErr) + } + t.Logf("PASS: %s", test.description) + } +} + +func TestTotal(t *testing.T) { + var expected uint64 = 18446744073709551615 + if actual := Total(); actual != expected { + t.Errorf("Total() expected %d, Actual %d", expected, actual) + } +} + +func BenchmarkSquare(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + + for i := 0; i < b.N; i++ { + + for _, test := range squareTests { + Square(test.input) + } + + } +} + +func BenchmarkTotal(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + for i := 0; i < b.N; i++ { + Total() + } +} diff --git a/go/gross-store/.exercism/config.json b/go/gross-store/.exercism/config.json new file mode 100644 index 0000000..ddecac8 --- /dev/null +++ b/go/gross-store/.exercism/config.json @@ -0,0 +1,20 @@ +{ + "blurb": "Learn about maps by selling items by the dozen at the Gross Store.", + "authors": [ + "chocopowwwa" + ], + "contributors": [ + "MiroslavGatsanoga" + ], + "files": { + "solution": [ + "gross_store.go" + ], + "test": [ + "gross_store_test.go" + ], + "exemplar": [ + ".meta/exemplar.go" + ] + } +} diff --git a/go/gross-store/.exercism/metadata.json b/go/gross-store/.exercism/metadata.json new file mode 100644 index 0000000..20868b8 --- /dev/null +++ b/go/gross-store/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"gross-store","id":"7bfbc74502004cb3867b5bf345b7b1b0","url":"https://exercism.org/tracks/go/exercises/gross-store","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/go/gross-store/HELP.md b/go/gross-store/HELP.md new file mode 100644 index 0000000..47f71b6 --- /dev/null +++ b/go/gross-store/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit gross_store.go` 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 [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/go/gross-store/HINTS.md b/go/gross-store/HINTS.md new file mode 100644 index 0000000..8bffb63 --- /dev/null +++ b/go/gross-store/HINTS.md @@ -0,0 +1,31 @@ +# Hints + +## General + +- [Go by example map][gobyexample-map] +- [Go maps in action][goblog-map] + +## 1. Store the unit of measurement in your program + +- To store the measurement in your program, you can use map literal, see [go blog about map][goblog-map] + +## 2. Create a new bill + +- To create a new bill, you all you need to do is reinitialize the customer, see [go blog about map][goblog-map] + +## 3. Add item to the customer bill + +- To check whether the given unit of measurement is correct, you can test your measurement map for a key without retrieving a value, see [go blog about map][goblog-map] + +## 4. Remove item from the customer bill + +- To check whether the given item is in customer bill, you can test your measurement map for a key without retrieving a value, see [go blog about map][goblog-map] + +- To check whether the given unit of measurement is correct, you can test your measurement map for a key without retrieving a value, see [go blog about map][goblog-map] + +## 5. Return the number of specific item that is in the customer bill + +- To check whether the given item is in customer bill, you can test your measurement map for a key without retrieving a value, see [go blog about map][goblog-map] + +[gobyexample-map]: https://gobyexample.com/maps +[goblog-map]: https://blog.golang.org/maps \ No newline at end of file diff --git a/go/gross-store/README.md b/go/gross-store/README.md new file mode 100644 index 0000000..cfb4b3b --- /dev/null +++ b/go/gross-store/README.md @@ -0,0 +1,159 @@ +# Gross Store + +Welcome to Gross Store on Exercism's Go 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 + +In go, `map` is a built-in data type that maps keys to values. In other programming language, you might be familiar with the concept of `map` as a dictionary, hash table, key/value store or an associative array. + +Syntactically, `map` looks like this: + +```go +map[KeyType]ElementType +``` + +It is also important to know that each key is unique, meaning that assigning the same key twice will overwrite the value of the corresponding key. + +To create a map, you can do: + +```go + // With map literal + foo := map[string]int{} +``` + +or + +```go + // or with make function + foo := make(map[string]int) +``` + +Here are some operations that you can do with a map + +```go + // Add a value in a map with the `=` operator: + foo["bar"] = 42 + // Here we update the element of `bar` + foo["bar"] = 73 + // To retrieve a map value, you can use + baz := foo["bar"] + // To delete an item from a map, you can use + delete(foo, "bar") +``` + +If you try to retrieve the value for a key which does not exist in the map, it will return the zero value of the value type. +This can confuse you, especially if the default value of your `ElementType` (for example, 0 for an int), is a valid value. +To check whether a key exists in your map, you can use + +```go + value, exists := foo["baz"] + // If the key "baz" does not exist, + // value: 0; exists: false +``` + +## Instructions + +A friend of yours has an old wholesale store called **Gross Store**. +The name comes from the quantity of the item that the store sell: it's all in [gross unit][gross-unit]. +Your friend asked you to implement a point of sale (POS) system for his store. +**First, you want to build a prototype for it.** +**In your prototype, your system will only record the quantity.** +Your friend gave you a list of measurements to help you: + +| Unit | Score | +| ------------------ | ----- | +| quarter_of_a_dozen | 3 | +| half_of_a_dozen | 6 | +| dozen | 12 | +| small_gross | 120 | +| gross | 144 | +| great_gross | 1728 | + +## 1. Store the unit of measurement in your program + +In order to use the measurement, you need to store the measurement in your program. + +```go +units := Units() +fmt.Println(units) +// Output: map[...] with entries like ("dozen": 12) +``` + +## 2. Create a new customer bill + +You need to implement a function that create a new (empty) bill for the customer. + +```go +bill := NewBill() +fmt.Println(bill) +// Output: map[] +``` + +## 3. Add an item to the customer bill + +To implement this, you'll need to: + +- Return `false` if the given `unit` is not in the `units` map. +- Otherwise add the item to the customer `bill`, indexed by the item name, then return `true`. + +```go +bill := NewBill() +units := Units() +ok := AddItem(bill, units, "carrot", "dozen") +fmt.Println(ok) +// Output: true (since dozen is a valid unit) +``` + +> Note that the returned value is type `bool`. + +## 4. Remove an item from the customer bill + +To implement this, you'll need to: + +- Return `false` if the given item is **not** in the bill +- Return `false` if the given `unit` is not in the `units` map. +- Return `false` if the new quantity would be less than 0. +- If the new quantity is 0, completely remove the item from the `bill` then return `true`. +- Otherwise, reduce the quantity of the item and return `true`. + +```go +bill := NewBill() +units := Units() +ok := RemoveItem(bill, units, "carrot", "dozen") +fmt.Println(ok) +// Output: false (because there are no carrots in the bill) +``` + +> Note that the returned value is type `bool`. + +## 5. Return the quantity of a specific item that is in the customer bill + +To implement this, you'll need to: + +- Return `0` and `false` if the `item` is not in the bill. +- Otherwise, return the quantity of the item in the `bill` and `true`. + +```go +bill := map[string]int{"carrot", 12, "grapes", 3} +qty, ok := GetItem(bill, "carrot") +fmt.Println(qty) +// Output: 12 +fmt.Println(ok) +// Output: true +``` + +> Note that the returned value are types `int` and `bool`. + +[gross-unit]: https://en.wikipedia.org/wiki/Gross_(unit) + +## Source + +### Created by + +- @chocopowwwa + +### Contributed to by + +- @MiroslavGatsanoga \ No newline at end of file diff --git a/go/gross-store/go.mod b/go/gross-store/go.mod new file mode 100644 index 0000000..0dc0f2f --- /dev/null +++ b/go/gross-store/go.mod @@ -0,0 +1,3 @@ +module gross + +go 1.16 diff --git a/go/gross-store/gross_store.go b/go/gross-store/gross_store.go new file mode 100644 index 0000000..a826b52 --- /dev/null +++ b/go/gross-store/gross_store.go @@ -0,0 +1,59 @@ +package gross + +// Units stores the Gross Store unit measurements. +func Units() map[string]int { + return map[string]int{ + "quarter_of_a_dozen": 3, + "half_of_a_dozen": 6, + "dozen": 12, + "small_gross": 120, + "gross": 144, + "great_gross": 1728, + } +} + +// NewBill creates a new bill. +func NewBill() map[string]int { + return map[string]int{} +} + +// AddItem adds an item to customer bill. +func AddItem(bill, units map[string]int, item, unit string) bool { + val, exists := units[unit] + if !exists { + return false + } + + bill[item] += val + return true +} + +// RemoveItem removes an item from customer bill. +func RemoveItem(bill, units map[string]int, item, unit string) bool { + qty, exists := bill[item] + if !exists { + return false + } + + val, exists := units[unit] + if !exists { + return false + } + + if qty - val < 0 { + return false + } + + if qty - val == 0 { + delete(bill, item) + } else { + bill[item] -= val + } + return true +} + +// GetItem returns the quantity of an item that the customer has in his/her bill. +func GetItem(bill map[string]int, item string) (int, bool) { + qty, exists := bill[item] + return qty, exists +} diff --git a/go/gross-store/gross_store_test.go b/go/gross-store/gross_store_test.go new file mode 100644 index 0000000..35fcebf --- /dev/null +++ b/go/gross-store/gross_store_test.go @@ -0,0 +1,255 @@ +package gross + +import ( + "testing" +) + +type entry struct { + name string + unit string + qty int +} + +func TestUnits(t *testing.T) { + tests := []struct { + name string + qty int + }{ + {"quarter_of_a_dozen", 3}, + {"half_of_a_dozen", 6}, + {"dozen", 12}, + {"small_gross", 120}, + {"gross", 144}, + {"great_gross", 1728}, + } + + units := Units() + for _, tt := range tests { + qty, ok := units[tt.name] + + if !ok { + t.Errorf(`Unit "%s" not found!`, tt.name) + continue + } + + if qty != tt.qty { + t.Errorf(`Unit "%s" should have quantity %d, found %d`, tt.name, tt.qty, qty) + } + } + +} +func TestAddItem(t *testing.T) { + tests := []struct { + name string + entry []entry + expected bool + }{ + { + "Invalid measurement unit", + []entry{ + {"pasta", "", 0}, + {"onion", "quarter", 0}, + {"pasta", "pound", 0}, + }, + false, + }, + { + "Valid measurement unit", + []entry{ + {"peas", "quarter_of_a_dozen", 3}, + {"tomato", "half_of_a_dozen", 6}, + {"chili", "dozen", 12}, + {"cucumber", "small_gross", 120}, + {"potato", "gross", 144}, + {"zucchini", "great_gross", 1728}, + }, + true, + }, + { + "check quantity of item added twice", + []entry{ + {"peas", "quarter_of_a_dozen", 3}, + {"peas", "quarter_of_a_dozen", 6}, + {"tomato", "half_of_a_dozen", 6}, + {"tomato", "quarter_of_a_dozen", 9}, + }, + true, + }, + } + units := Units() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + bill := NewBill() + for _, item := range tt.entry { + ok := AddItem(bill, units, item.name, item.unit) + if ok != tt.expected { + t.Errorf("Expected %t from AddItem, found %t at %v", tt.expected, ok, item.name) + } + + itemQty, ok := bill[item.name] + if ok != tt.expected { + t.Errorf("Could not find item %s in customer bill", item.name) + } + + if itemQty != item.qty { + t.Errorf("Expected %s to have quantity %d in customer bill, found %d", item.name, item.qty, itemQty) + } + } + }) + } +} + +func TestRemoveItem(t *testing.T) { + type expectedItem struct { + name string + unit string + qty int + exists bool + } + + tests := []struct { + name string + remove []expectedItem + expected bool + }{ + {"Item Not found in bill", + []expectedItem{ + {"papaya", "gross", 0, false}, + }, + false, + }, + {"Invalid measurement unit", + []expectedItem{ + {"peas", "pound", 3, true}, + {"tomato", "kilogram", 6, true}, + {"cucumber", "stone", 120, true}, + }, + false, + }, + {"Resulted qty less than 0", + []expectedItem{ + {"peas", "half_of_a_dozen", 3, true}, + {"tomato", "dozen", 6, true}, + {"chili", "small_gross", 12, true}, + {"cucumber", "gross", 120, true}, + {"potato", "great_gross", 144, true}, + }, + false, + }, + {"Should delete the item if 0", + []expectedItem{ + {"peas", "quarter_of_a_dozen", 0, false}, + {"tomato", "half_of_a_dozen", 0, false}, + {"chili", "dozen", 0, false}, + {"cucumber", "small_gross", 0, false}, + {"potato", "gross", 0, false}, + {"zucchini", "great_gross", 0, false}, + }, + true, + }, + {"Should reduce the qty", + []expectedItem{ + {"chili", "half_of_a_dozen", 6, true}, + {"cucumber", "dozen", 108, true}, + {"zucchini", "gross", 1584, true}, + }, + true, + }, + } + + units := Units() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + bill := setupInitialBillData() + for _, item := range tt.remove { + ok := RemoveItem(bill, units, item.name, item.unit) + if ok != tt.expected { + t.Errorf("Expected %t from RemoveItem, found %t at %v", tt.expected, ok, item.name) + } + + itemQty, ok := bill[item.name] + if ok != item.exists { + t.Errorf("Could not find item %s in customer bill", item.name) + } + if itemQty != item.qty { + t.Errorf("Expected %s to have quantity %d in customer bill, found %d", item.name, item.qty, itemQty) + } + } + }) + } +} + +func TestNewBill(t *testing.T) { + // Success, zero out the bill + t.Run("Should reset customerbill", func(t *testing.T) { + bill := NewBill() + + if len(bill) != 0 { + t.Error("Customer bill must be empty") + } + }) +} + +func TestGetItem(t *testing.T) { + type expectedItem struct { + name string + expected bool + qty int + } + + test := []struct { + name string + getItem []expectedItem + }{ + { + "Item Not found in bill", + []expectedItem{ + {"grape", false, 0}, + }, + }, + { + "Success", + []expectedItem{ + {"peas", true, 3}, + {"tomato", true, 6}, + {"chili", true, 12}, + {"cucumber", true, 120}, + {"potato", true, 144}, + {"zucchini", true, 1728}, + }, + }, + } + + for _, tt := range test { + t.Run(tt.name, func(t *testing.T) { + bill := setupInitialBillData() + for _, item := range tt.getItem { + itemQty, ok := GetItem(bill, item.name) + + if ok != item.expected { + msg := "Could not find item %s in customer bill, expected %t" + if item.expected == false { + msg = "Found item %s in customer bill, expected %t" + } + + t.Errorf(msg, item.name, item.expected) + } + + if itemQty != item.qty { + t.Errorf("Expected %s to have quantity %d in customer bill, found %d", item.name, item.qty, itemQty) + } + } + }) + } +} + +func setupInitialBillData() map[string]int { + bill := NewBill() + bill["peas"] = 3 + bill["tomato"] = 6 + bill["chili"] = 12 + bill["cucumber"] = 120 + bill["potato"] = 144 + bill["zucchini"] = 1728 + return bill +} diff --git a/go/isbn-verifier/.exercism/config.json b/go/isbn-verifier/.exercism/config.json new file mode 100644 index 0000000..1ad93e4 --- /dev/null +++ b/go/isbn-verifier/.exercism/config.json @@ -0,0 +1,33 @@ +{ + "blurb": "Check if a given string is a valid ISBN-10 number.", + "authors": [ + "creaaa" + ], + "contributors": [ + "bitfield", + "ekingery", + "ferhatelmas", + "h311ion", + "hilary", + "kytrinyx", + "leenipper", + "sebito91", + "tinsch" + ], + "files": { + "solution": [ + "isbn_verifier.go" + ], + "test": [ + "isbn_verifier_test.go" + ], + "example": [ + ".meta/example.go" + ], + "editor": [ + "cases_test.go" + ] + }, + "source": "Converting a string into a number and some basic processing utilizing a relatable real world example.", + "source_url": "https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digit_calculation" +} diff --git a/go/isbn-verifier/.exercism/metadata.json b/go/isbn-verifier/.exercism/metadata.json new file mode 100644 index 0000000..337b72f --- /dev/null +++ b/go/isbn-verifier/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"isbn-verifier","id":"c2a9f9ef655f45b1b42a5530b24252d1","url":"https://exercism.org/tracks/go/exercises/isbn-verifier","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/go/isbn-verifier/HELP.md b/go/isbn-verifier/HELP.md new file mode 100644 index 0000000..3df23d0 --- /dev/null +++ b/go/isbn-verifier/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit isbn_verifier.go` 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 [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/go/isbn-verifier/README.md b/go/isbn-verifier/README.md new file mode 100644 index 0000000..df162f6 --- /dev/null +++ b/go/isbn-verifier/README.md @@ -0,0 +1,69 @@ +# Isbn Verifier + +Welcome to Isbn Verifier on Exercism's Go Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +The [ISBN-10 verification process](https://en.wikipedia.org/wiki/International_Standard_Book_Number) is used to validate book identification +numbers. These normally contain dashes and look like: `3-598-21508-8` + +## ISBN + +The ISBN-10 format is 9 digits (0 to 9) plus one check character (either a digit or an X only). In the case the check character is an X, this represents the value '10'. These may be communicated with or without hyphens, and can be checked for their validity by the following formula: + +```text +(x1 * 10 + x2 * 9 + x3 * 8 + x4 * 7 + x5 * 6 + x6 * 5 + x7 * 4 + x8 * 3 + x9 * 2 + x10 * 1) mod 11 == 0 +``` + +If the result is 0, then it is a valid ISBN-10, otherwise it is invalid. + +## Example + +Let's take the ISBN-10 `3-598-21508-8`. We plug it in to the formula, and get: + +```text +(3 * 10 + 5 * 9 + 9 * 8 + 8 * 7 + 2 * 6 + 1 * 5 + 5 * 4 + 0 * 3 + 8 * 2 + 8 * 1) mod 11 == 0 +``` + +Since the result is 0, this proves that our ISBN is valid. + +## Task + +Given a string the program should check if the provided string is a valid ISBN-10. +Putting this into place requires some thinking about preprocessing/parsing of the string prior to calculating the check digit for the ISBN. + +The program should be able to verify ISBN-10 both with and without separating dashes. + +## Caveats + +Converting from strings to numbers can be tricky in certain languages. +Now, it's even trickier since the check digit of an ISBN-10 may be 'X' (representing '10'). For instance `3-598-21507-X` is a valid ISBN-10. + +## Bonus tasks + +* Generate a valid ISBN-13 from the input ISBN-10 (and maybe verify it again with a derived verifier). + +* Generate valid ISBN, maybe even from a given starting ISBN. + +## Source + +### Created by + +- @creaaa + +### Contributed to by + +- @bitfield +- @ekingery +- @ferhatelmas +- @h311ion +- @hilary +- @kytrinyx +- @leenipper +- @sebito91 +- @tinsch + +### Based on + +Converting a string into a number and some basic processing utilizing a relatable real world example. - https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digit_calculation \ No newline at end of file diff --git a/go/isbn-verifier/cases_test.go b/go/isbn-verifier/cases_test.go new file mode 100644 index 0000000..09e0441 --- /dev/null +++ b/go/isbn-verifier/cases_test.go @@ -0,0 +1,29 @@ +package isbn + +// Source: exercism/problem-specifications +// Commit: 3134243 isbn-verifier: Crafted input to catch more incorrect algorithms (#1255) +// Problem Specifications Version: 2.7.0 + +var testCases = []struct { + isbn string + expected bool + description string +}{ + {"3-598-21508-8", true, "valid isbn number"}, + {"3-598-21508-9", false, "invalid isbn check digit"}, + {"3-598-21507-X", true, "valid isbn number with a check digit of 10"}, + {"3-598-21507-A", false, "check digit is a character other than X"}, + {"3-598-P1581-X", false, "invalid character in isbn"}, + {"3-598-2X507-9", false, "X is only valid as a check digit"}, + {"3598215088", true, "valid isbn without separating dashes"}, + {"359821507X", true, "isbn without separating dashes and X as check digit"}, + {"359821507", false, "isbn without check digit and dashes"}, + {"3598215078X", false, "too long isbn and no dashes"}, + {"00", false, "too short isbn"}, + {"3-598-21507", false, "isbn without check digit"}, + {"3-598-21515-X", false, "check digit of X should not be used for 0"}, + {"", false, "empty isbn"}, + {"134456729", false, "input is 9 characters"}, + {"3132P34035", false, "invalid characters are not ignored"}, + {"98245726788", false, "input is too long but contains a valid isbn"}, +} diff --git a/go/isbn-verifier/go.mod b/go/isbn-verifier/go.mod new file mode 100644 index 0000000..a889cf1 --- /dev/null +++ b/go/isbn-verifier/go.mod @@ -0,0 +1,3 @@ +module isbn + +go 1.13 diff --git a/go/isbn-verifier/isbn_verifier.go b/go/isbn-verifier/isbn_verifier.go new file mode 100644 index 0000000..9ace7b3 --- /dev/null +++ b/go/isbn-verifier/isbn_verifier.go @@ -0,0 +1,5 @@ +package isbn + +func IsValidISBN(isbn string) bool { + panic("Please implement the IsValidISBN function") +} diff --git a/go/isbn-verifier/isbn_verifier_test.go b/go/isbn-verifier/isbn_verifier_test.go new file mode 100644 index 0000000..599e3b1 --- /dev/null +++ b/go/isbn-verifier/isbn_verifier_test.go @@ -0,0 +1,28 @@ +package isbn + +import ( + "testing" +) + +func TestIsValidISBN(t *testing.T) { + for _, test := range testCases { + observed := IsValidISBN(test.isbn) + if observed == test.expected { + t.Logf("PASS: %s", test.description) + } else { + t.Errorf("FAIL: %s\nIsValidISBN(%q)\nExpected: %t, Actual: %t", + test.description, test.isbn, test.expected, observed) + } + } +} + +func BenchmarkIsValidISBN(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + for i := 0; i < b.N; i++ { + for _, n := range testCases { + IsValidISBN(n.isbn) + } + } +} diff --git a/go/lasagna/.exercism/config.json b/go/lasagna/.exercism/config.json new file mode 100644 index 0000000..5dbbba1 --- /dev/null +++ b/go/lasagna/.exercism/config.json @@ -0,0 +1,25 @@ +{ + "blurb": "Learn about packages, functions, and variables by helping Gopher cook lasagna.", + "authors": [ + "tehsphinx" + ], + "contributors": [ + "ekingery", + "andrerfcsantos", + "bobtfish" + ], + "forked_from": [ + "csharp/lucians-luscious-lasagna" + ], + "files": { + "solution": [ + "lasagna.go" + ], + "test": [ + "lasagna_test.go" + ], + "exemplar": [ + ".meta/exemplar.go" + ] + } +} diff --git a/go/lasagna/.exercism/metadata.json b/go/lasagna/.exercism/metadata.json new file mode 100644 index 0000000..4852dbe --- /dev/null +++ b/go/lasagna/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"lasagna","id":"e418a5b0bb904f5c9433c52db1a8bb0a","url":"https://exercism.org/tracks/go/exercises/lasagna","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/go/lasagna/HELP.md b/go/lasagna/HELP.md new file mode 100644 index 0000000..1edef7c --- /dev/null +++ b/go/lasagna/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit lasagna.go` 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 [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/go/lasagna/HINTS.md b/go/lasagna/HINTS.md new file mode 100644 index 0000000..be4c9b1 --- /dev/null +++ b/go/lasagna/HINTS.md @@ -0,0 +1,44 @@ +# Hints + +## General + +- An [integer value][integers] can be defined as one or more consecutive digits. +- If you see a `panic:` error when running the tests, this is because you have not implemented one of the functions (it should say which one) or you have left the boilerplate in place. You need to remove the `panic(...)` line from the supplied code and replace it with a real implementation. + +## 1. Define the expected oven time in minutes + +- You need to define a [constant][constants] and assign it the expected oven time in minutes. +- If you see an `undefined: OvenTime` error then double check that you have the constant defined. +- If you see an `invalid operation: got != tt.expected (mismatched types float64 and int)` error then you have likely put a decimal point into the `OvenTime` causing Go to infer the type as a floating point number. Remove the decimal and the type will be inferred as an `int`. +- If you see a `syntax error: non-declaration statement outside function body` error then it is likely that you forgot the `const` keyword. +- If you see a `syntax error: unexpected :=, expecting =` error then you are likely trying to assign the constant using `:=` like a variable; constants are assigned using `=` not `:=`. + +## 2. Calculate the remaining oven time in minutes + +- You need to define a [function][functions] with a single parameter. +- You have to [explicitly return an integer][return] from a function. +- The function's parameter is an [integer][integers]. +- You can [call][calls] one of the other functions you've defined previously. +- You can use the [mathematical operator for subtraction][operators] to subtract values. + +## 3. Calculate the preparation time in minutes + +- You need to define a [function][functions] with a single parameter. +- You have to [explicitly return an integer][return] from a function. +- The function's parameter is an [integer][integers]. +- You can use the [mathematical operator for multiplication][operators] to multiply values. + +## 4. Calculate the elapsed working time in minutes + +- You need to define a [function][functions] with two parameters. +- You have to [explicitly return an integer][return] from a function. +- The function's parameter is an [integer][integers]. +- You can [call][calls] one of the other functions you've defined previously. +- You can use the [mathematical operator for addition][operators] to add values. + +[functions]: https://tour.golang.org/basics/4 +[return]: https://golang.org/ref/spec#Return_statements +[operators]: https://golang.org/ref/spec#Operators +[integers]: https://golang.org/ref/spec#Integer_literals +[calls]: https://golang.org/ref/spec#Calls +[constants]: https://tour.golang.org/basics/15 \ No newline at end of file diff --git a/go/lasagna/README.md b/go/lasagna/README.md new file mode 100644 index 0000000..b862fa9 --- /dev/null +++ b/go/lasagna/README.md @@ -0,0 +1,151 @@ +# Gopher's Gorgeous Lasagna + +Welcome to Gopher's Gorgeous Lasagna on Exercism's Go 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 + +[Go](https://golang.org) is a statically typed, compiled programming language. +This exercise introduces three major language features: Packages, Functions, and Variables. + +## Packages + +Go applications are organized in packages. +A package is a collection of source files located in the same directory. +All source files in a directory must share the same package name. +When a package is imported, only entities (functions, types, variables, constants) who's name starts with a capital letter can be used / accessed. +The recommended style of naming in Go is that identifiers will be named using `camelCase`, except for those meant to be accessible across packages which should be `CamelCase`. + +```go +package lasagna +``` + +## Variables + +Go is statically-typed, which means all variables [must have a defined type](https://en.wikipedia.org/wiki/Type_system) at compile-time. + +Variables can be defined by explicitly specifying a type: + +```go +var explicit int // Explicitly typed +``` + +You can also use an initializer, and the compiler will assign the variable type to match the type of the initializer. + +```go +implicit := 10 // Implicitly typed as an int +``` + +Once declared, variables can be assigned values using the `=` operator. +Once declared, a variable's type can never change. + +```go +count := 1 // Assign initial value +count = 2 // Update to new value + +count = false // This throws a compiler error due to assigning a non `int` type +``` + +## Constants + +Constants hold a piece of data just like variables, but their value cannot change during the execution of the program. + +Constants are defined using the `const` keyword and can be numbers, characters, strings or booleans: + +```go +const Age = 21 // Defines a numeric constant 'Age' with the value of 21 +``` + +## Functions + +Go functions accept zero or more parameters. +Parameters must be explicitly typed, there is no type inference. + +Values are returned from functions using the `return` keyword. + +A function is invoked by specifying the function name and passing arguments for each of the function's parameters. + +Note that Go supports two types of comments. +Single line comments are preceded by `//` and multiline comments are inserted between `/*` and `*/`. + +```go +package greeting + +// Hello is a public function +func Hello (name string) string { + return hi(name) +} + +// hi is a private function +func hi (name string) string { + return "hi " + name +} +``` + +## Instructions + +In this exercise you're going to write some code to help you cook a brilliant lasagna from your favorite cooking book. + +You have four tasks, all related to the time spent cooking the lasagna. + +## 1. Define the expected oven time in minutes + +Define the `OvenTime` constant with how many minutes the lasagna should be in the oven. According to the cooking book, the expected oven time in minutes is 40: + +```go +OvenTime +// Output: 40 +``` + +## 2. Calculate the remaining oven time in minutes + +Define the `RemainingOvenTime()` function that takes the actual minutes the lasagna has been in the oven as a parameter and returns how many minutes the lasagna still has to remain in the oven, based on the expected oven time in minutes from the previous task. + +```go +func RemainingOvenTime(actual int) int { + // TODO +} + +RemainingOvenTime(30) +// Output: 10 +``` + +## 3. Calculate the preparation time in minutes + +Define the `PreparationTime` function that takes the number of layers you added to the lasagna as a parameter and returns how many minutes you spent preparing the lasagna, assuming each layer takes you 2 minutes to prepare. + +```go +func PreparationTime(numberOfLayers int) int { + // TODO +} + +PreparationTime(2) +// Output: 4 +``` + +## 4. Calculate the elapsed working time in minutes + +Define the `ElapsedTime` function that takes two parameters: the first parameter is the number of layers you added to the lasagna, and the second parameter is the number of minutes the lasagna has been in the oven. +The function should return how many minutes in total you've worked on cooking the lasagna, which is the sum of the preparation time in minutes, and the time in minutes the lasagna has spent in the oven at the moment. + +```go +func ElapsedTime(numberOfLayers, actualMinutesInOven int) int { + // TODO +} + +ElapsedTime(3, 20) +// Output: 26 +``` + +## Source + +### Created by + +- @tehsphinx + +### Contributed to by + +- @ekingery +- @andrerfcsantos +- @bobtfish \ No newline at end of file diff --git a/go/lasagna/go.mod b/go/lasagna/go.mod new file mode 100644 index 0000000..d53312e --- /dev/null +++ b/go/lasagna/go.mod @@ -0,0 +1,3 @@ +module lasagna + +go 1.14 diff --git a/go/lasagna/lasagna.go b/go/lasagna/lasagna.go new file mode 100644 index 0000000..a7115a9 --- /dev/null +++ b/go/lasagna/lasagna.go @@ -0,0 +1,17 @@ +package lasagna + +const OvenTime = 40; +// RemainingOvenTime returns the remaining minutes based on the `actual` minutes already in the oven. +func RemainingOvenTime(actualMinutesInOven int) int { + return OvenTime - actualMinutesInOven; +} + +// PreparationTime calculates the time needed to prepare the lasagna based on the amount of layers. +func PreparationTime(numberOfLayers int) int { + return numberOfLayers * 2 +} + +// ElapsedTime calculates the total time needed to create and bake a lasagna. +func ElapsedTime(numberOfLayers, actualMinutesInOven int) int { + return PreparationTime(numberOfLayers) + actualMinutesInOven +} diff --git a/go/lasagna/lasagna_test.go b/go/lasagna/lasagna_test.go new file mode 100644 index 0000000..b7a08ee --- /dev/null +++ b/go/lasagna/lasagna_test.go @@ -0,0 +1,94 @@ +package lasagna + +import "testing" + +type lasagnaTests struct { + name string + layers, time, expected int +} + +func TestOvenTime(t *testing.T) { + tests := []lasagnaTests{ + { + name: "Calculates how many minutes the lasagna should be in the oven", + layers: 0, + time: 40, + expected: 40, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := OvenTime; got != tt.expected { + t.Errorf("OvenTime(%d) = %d; want %d", tt.expected, got, tt.expected) + } + }) + } +} + +func TestRemainingOvenTime(t *testing.T) { + tests := []lasagnaTests{ + { + name: "Remaining minutes in oven", + layers: 0, + time: 15, + expected: 15, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := RemainingOvenTime(25); got != tt.time { + t.Errorf("RemainingOvenTime(%d) = %d; want %d", tt.expected, got, tt.expected) + } + }) + } + +} +func TestPreparationTime(t *testing.T) { + tests := []lasagnaTests{ + { + name: "Preparation time in minutes for one layer", + layers: 1, + time: 0, + expected: 2, + }, + { + name: "Preparation time in minutes for multiple layer", + layers: 4, + time: 0, + expected: 8, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := PreparationTime(tt.layers); got != tt.expected { + t.Errorf("PreparationTime(%d) = %d; want %d", tt.layers, got, tt.expected) + } + }) + + } +} + +func TestElapsedTime(t *testing.T) { + tests := []lasagnaTests{ + { + name: "Total time in minutes for one layer", + layers: 1, + time: 30, + expected: 32, + }, + { + name: "Total time in minutes for multiple layer", + layers: 4, + time: 8, + expected: 16, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ElapsedTime(tt.layers, tt.time); got != tt.expected { + t.Errorf("ElapsedTime(%d, %d) = %d; want %d", tt.layers, tt.time, got, tt.expected) + } + }) + + } +} diff --git a/go/luhn/.exercism/config.json b/go/luhn/.exercism/config.json new file mode 100644 index 0000000..e1bdeb2 --- /dev/null +++ b/go/luhn/.exercism/config.json @@ -0,0 +1,37 @@ +{ + "blurb": "Given a number determine whether or not it is valid per the Luhn formula.", + "authors": [ + "soniakeys" + ], + "contributors": [ + "alebaffa", + "bitfield", + "da-edra", + "ekingery", + "ferhatelmas", + "hilary", + "kytrinyx", + "leenipper", + "michaelorr", + "petertseng", + "robphoenix", + "sebito91", + "tehsphinx" + ], + "files": { + "solution": [ + "luhn.go" + ], + "test": [ + "luhn_test.go" + ], + "example": [ + ".meta/example.go" + ], + "editor": [ + "cases_test.go" + ] + }, + "source": "The Luhn Algorithm on Wikipedia", + "source_url": "http://en.wikipedia.org/wiki/Luhn_algorithm" +} diff --git a/go/luhn/.exercism/metadata.json b/go/luhn/.exercism/metadata.json new file mode 100644 index 0000000..cac3855 --- /dev/null +++ b/go/luhn/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"luhn","id":"848a867390e5471ab5f927ba5dad86a7","url":"https://exercism.org/tracks/go/exercises/luhn","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/go/luhn/.tool-versions b/go/luhn/.tool-versions new file mode 100644 index 0000000..ac3cddf --- /dev/null +++ b/go/luhn/.tool-versions @@ -0,0 +1,2 @@ +golang 1.17.2 +kubectx 0.9.3 diff --git a/go/luhn/HELP.md b/go/luhn/HELP.md new file mode 100644 index 0000000..851598e --- /dev/null +++ b/go/luhn/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit luhn.go` 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 [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/go/luhn/README.md b/go/luhn/README.md new file mode 100644 index 0000000..cab2202 --- /dev/null +++ b/go/luhn/README.md @@ -0,0 +1,95 @@ +# Luhn + +Welcome to Luhn on Exercism's Go Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +Given a number determine whether or not it is valid per the Luhn formula. + +The [Luhn algorithm](https://en.wikipedia.org/wiki/Luhn_algorithm) is +a simple checksum formula used to validate a variety of identification +numbers, such as credit card numbers and Canadian Social Insurance +Numbers. + +The task is to check if a given string is valid. + +## Validating a Number + +Strings of length 1 or less are not valid. Spaces are allowed in the input, +but they should be stripped before checking. All other non-digit characters +are disallowed. + +### Example 1: valid credit card number + +```text +4539 3195 0343 6467 +``` + +The first step of the Luhn algorithm is to double every second digit, +starting from the right. We will be doubling + +```text +4_3_ 3_9_ 0_4_ 6_6_ +``` + +If doubling the number results in a number greater than 9 then subtract 9 +from the product. The results of our doubling: + +```text +8569 6195 0383 3437 +``` + +Then sum all of the digits: + +```text +8+5+6+9+6+1+9+5+0+3+8+3+3+4+3+7 = 80 +``` + +If the sum is evenly divisible by 10, then the number is valid. This number is valid! + +### Example 2: invalid credit card number + +```text +8273 1232 7352 0569 +``` + +Double the second digits, starting from the right + +```text +7253 2262 5312 0539 +``` + +Sum the digits + +```text +7+2+5+3+2+2+6+2+5+3+1+2+0+5+3+9 = 57 +``` + +57 is not evenly divisible by 10, so this number is not valid. + +## Source + +### Created by + +- @soniakeys + +### Contributed to by + +- @alebaffa +- @bitfield +- @da-edra +- @ekingery +- @ferhatelmas +- @hilary +- @kytrinyx +- @leenipper +- @michaelorr +- @petertseng +- @robphoenix +- @sebito91 +- @tehsphinx + +### Based on + +The Luhn Algorithm on Wikipedia - http://en.wikipedia.org/wiki/Luhn_algorithm \ No newline at end of file diff --git a/go/luhn/cases_test.go b/go/luhn/cases_test.go new file mode 100644 index 0000000..92f9ebd --- /dev/null +++ b/go/luhn/cases_test.go @@ -0,0 +1,102 @@ +package luhn + +// Source: exercism/problem-specifications +// Commit: f375a46 luhn: Update non-ASCII test case +// Problem Specifications Version: 1.6.1 + +var testCases = []struct { + description string + input string + ok bool +}{ + { + "single digit strings can not be valid", + "1", + false, + }, + { + "a single zero is invalid", + "0", + false, + }, + { + "a simple valid SIN that remains valid if reversed", + "059", + true, + }, + { + "a simple valid SIN that becomes invalid if reversed", + "59", + true, + }, + { + "a valid Canadian SIN", + "055 444 285", + true, + }, + { + "invalid Canadian SIN", + "055 444 286", + false, + }, + { + "invalid credit card", + "8273 1232 7352 0569", + false, + }, + { + "valid number with an even number of digits", + "095 245 88", + true, + }, + { + "valid number with an odd number of spaces", + "234 567 891 234", + true, + }, + { + "valid strings with a non-digit added at the end become invalid", + "059a", + false, + }, + { + "valid strings with punctuation included become invalid", + "055-444-285", + false, + }, + { + "valid strings with symbols included become invalid", + "055# 444$ 285", + false, + }, + { + "single zero with space is invalid", + " 0", + false, + }, + { + "more than a single zero is valid", + "0000 0", + true, + }, + { + "input digit 9 is correctly converted to output digit 9", + "091", + true, + }, + { + "valid number with an odd number of digits and non-zero first digit", + "109", + true, + }, + { + "using ascii value for non-doubled non-digit isn't allowed", + "055b 444 285", + false, + }, + { + "using ascii value for doubled non-digit isn't allowed", + ":9", + false, + }, +} diff --git a/go/luhn/go.mod b/go/luhn/go.mod new file mode 100644 index 0000000..99deb40 --- /dev/null +++ b/go/luhn/go.mod @@ -0,0 +1,3 @@ +module luhn + +go 1.13 diff --git a/go/luhn/luhn.go b/go/luhn/luhn.go new file mode 100644 index 0000000..97cb7c3 --- /dev/null +++ b/go/luhn/luhn.go @@ -0,0 +1,33 @@ +package luhn + +import ( + "unicode" + "strings" +) + + +// Valid checks a given number for validity according to Luhn's formula +func Valid(card string) bool { + sum := 0 + card = strings.ReplaceAll(card, " ", "") + if len(card) <= 1 { + return false + } + for idx, char := range card { + if !unicode.IsDigit(char) { + return false + } + digit := int(char - '0') + if (len(card)-idx-1)%2 == 0 { + sum += digit + } else { + digit *= 2 + if digit > 9 { + sum += digit - 9 + } else { + sum += digit + } + } + } + return sum%10 == 0 +} diff --git a/go/luhn/luhn_test.go b/go/luhn/luhn_test.go new file mode 100644 index 0000000..c70fa0a --- /dev/null +++ b/go/luhn/luhn_test.go @@ -0,0 +1,20 @@ +package luhn + +import "testing" + +func TestValid(t *testing.T) { + for _, test := range testCases { + if ok := Valid(test.input); ok != test.ok { + t.Fatalf("Valid(%s): %s\n\t Expected: %t\n\t Got: %t", test.input, test.description, test.ok, ok) + } + } +} + +func BenchmarkValid(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + for i := 0; i < b.N; i++ { + Valid("2323 2005 7766 3554") + } +} diff --git a/go/protein-translation/.exercism/config.json b/go/protein-translation/.exercism/config.json new file mode 100644 index 0000000..143fbf3 --- /dev/null +++ b/go/protein-translation/.exercism/config.json @@ -0,0 +1,30 @@ +{ + "blurb": "Translate RNA sequences into proteins.", + "authors": [ + "Akasurde" + ], + "contributors": [ + "alebaffa", + "bitfield", + "ekingery", + "ferhatelmas", + "hilary", + "kytrinyx", + "leenipper", + "robphoenix", + "sebito91", + "tleen" + ], + "files": { + "solution": [ + "protein_translation.go" + ], + "test": [ + "protein_translation_test.go" + ], + "example": [ + ".meta/example.go" + ] + }, + "source": "Tyler Long" +} diff --git a/go/protein-translation/.exercism/metadata.json b/go/protein-translation/.exercism/metadata.json new file mode 100644 index 0000000..60b1e09 --- /dev/null +++ b/go/protein-translation/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"protein-translation","id":"1806e002ad7e45bf87a980c11a1bdac1","url":"https://exercism.org/tracks/go/exercises/protein-translation","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/go/protein-translation/HELP.md b/go/protein-translation/HELP.md new file mode 100644 index 0000000..fcee8cd --- /dev/null +++ b/go/protein-translation/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit protein_translation.go` 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 [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/go/protein-translation/README.md b/go/protein-translation/README.md new file mode 100644 index 0000000..060f689 --- /dev/null +++ b/go/protein-translation/README.md @@ -0,0 +1,70 @@ +# Protein Translation + +Welcome to Protein Translation on Exercism's Go Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +Translate RNA sequences into proteins. + +RNA can be broken into three nucleotide sequences called codons, and then translated to a polypeptide like so: + +RNA: `"AUGUUUUCU"` => translates to + +Codons: `"AUG", "UUU", "UCU"` +=> which become a polypeptide with the following sequence => + +Protein: `"Methionine", "Phenylalanine", "Serine"` + +There are 64 codons which in turn correspond to 20 amino acids; however, all of the codon sequences and resulting amino acids are not important in this exercise. If it works for one codon, the program should work for all of them. +However, feel free to expand the list in the test suite to include them all. + +There are also three terminating codons (also known as 'STOP' codons); if any of these codons are encountered (by the ribosome), all translation ends and the protein is terminated. + +All subsequent codons after are ignored, like this: + +RNA: `"AUGUUUUCUUAAAUG"` => + +Codons: `"AUG", "UUU", "UCU", "UAA", "AUG"` => + +Protein: `"Methionine", "Phenylalanine", "Serine"` + +Note the stop codon `"UAA"` terminates the translation and the final methionine is not translated into the protein sequence. + +Below are the codons and resulting Amino Acids needed for the exercise. + +Codon | Protein +:--- | :--- +AUG | Methionine +UUU, UUC | Phenylalanine +UUA, UUG | Leucine +UCU, UCC, UCA, UCG | Serine +UAU, UAC | Tyrosine +UGU, UGC | Cysteine +UGG | Tryptophan +UAA, UAG, UGA | STOP + +Learn more about [protein translation on Wikipedia](http://en.wikipedia.org/wiki/Translation_(biology)) + +## Source + +### Created by + +- @Akasurde + +### Contributed to by + +- @alebaffa +- @bitfield +- @ekingery +- @ferhatelmas +- @hilary +- @kytrinyx +- @leenipper +- @robphoenix +- @sebito91 +- @tleen + +### Based on + +Tyler Long \ No newline at end of file diff --git a/go/protein-translation/go.mod b/go/protein-translation/go.mod new file mode 100644 index 0000000..39a3172 --- /dev/null +++ b/go/protein-translation/go.mod @@ -0,0 +1,3 @@ +module protein + +go 1.13 diff --git a/go/protein-translation/protein_translation.go b/go/protein-translation/protein_translation.go new file mode 100644 index 0000000..993ab7a --- /dev/null +++ b/go/protein-translation/protein_translation.go @@ -0,0 +1,9 @@ +package protein + +func FromRNA(rna string) ([]string, error) { + panic("Please implement the FromRNA function") +} + +func FromCodon(codon string) (string, error) { + panic("Please implement the FromCodon function") +} diff --git a/go/protein-translation/protein_translation_detailed_test.go b/go/protein-translation/protein_translation_detailed_test.go new file mode 100644 index 0000000..8cd0994 --- /dev/null +++ b/go/protein-translation/protein_translation_detailed_test.go @@ -0,0 +1,35 @@ +//go:build detailed +// +build detailed + +package protein + +import ( + "fmt" + "testing" +) + +func BenchmarkCodonDetailed(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + for _, test := range codonTestCases { + b.Run(fmt.Sprintf("Codon%s", test.input), func(b *testing.B) { + for i := 0; i < b.N; i++ { + FromCodon(test.input) + } + }) + } +} + +func BenchmarkProteinDetailed(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + for _, test := range proteinTestCases { + b.Run(fmt.Sprintf("Protein%s", test.input), func(b *testing.B) { + for i := 0; i < b.N; i++ { + FromRNA(test.input) + } + }) + } +} diff --git a/go/protein-translation/protein_translation_test.go b/go/protein-translation/protein_translation_test.go new file mode 100644 index 0000000..435c95a --- /dev/null +++ b/go/protein-translation/protein_translation_test.go @@ -0,0 +1,189 @@ +package protein + +import ( + "reflect" + "testing" +) + +func TestErrorsNotNil(t *testing.T) { + if ErrStop == nil { + t.Fatalf("FAIL: ErrStop cannot be nil") + } + if ErrInvalidBase == nil { + t.Fatalf("FAIL: ErrInvalidBase cannot be nil") + } +} + +type codonCase struct { + input string + expected string + errorExpected error +} + +var codonTestCases = []codonCase{ + { + "AUG", + "Methionine", + nil, + }, + { + "UUU", + "Phenylalanine", + nil, + }, + { + "UUC", + "Phenylalanine", + nil, + }, + { + "UUA", + "Leucine", + nil, + }, + { + "UUG", + "Leucine", + nil, + }, + { + "UCG", + "Serine", + nil, + }, + { + "UAU", + "Tyrosine", + nil, + }, + { + "UAC", + "Tyrosine", + nil, + }, + { + "UGU", + "Cysteine", + nil, + }, + { + "UGG", + "Tryptophan", + nil, + }, + { + "UAA", + "", + ErrStop, + }, + { + "UAG", + "", + ErrStop, + }, + { + "UGA", + "", + ErrStop, + }, + { + "ABC", + "", + ErrInvalidBase, + }, +} + +func TestCodon(t *testing.T) { + for _, test := range codonTestCases { + actual, err := FromCodon(test.input) + if test.errorExpected != nil { + if test.errorExpected != err { + t.Fatalf("FAIL: Protein translation test: %s\nExpected error: %q\nActual error: %q", + test.input, test.errorExpected, err) + } + } else if err != nil { + t.Fatalf("FAIL: Protein translation test: %s\nExpected: %s\nGot error: %q", + test.input, test.expected, err) + } + if actual != test.expected { + t.Fatalf("FAIL: Protein translation test: %s\nExpected: %s\nActual: %s", + test.input, test.expected, actual) + } + t.Logf("PASS: Protein translation test: %s", test.input) + } +} + +type rnaCase struct { + input string + expected []string + errorExpected error +} + +var proteinTestCases = []rnaCase{ + { + "AUGUUUUCUUAAAUG", + []string{"Methionine", "Phenylalanine", "Serine"}, + nil, + }, + { + "AUGUUUUGG", + []string{"Methionine", "Phenylalanine", "Tryptophan"}, + nil, + }, + { + "AUGUUUUAA", + []string{"Methionine", "Phenylalanine"}, + nil, + }, + { + "UGGUGUUAUUAAUGGUUU", + []string{"Tryptophan", "Cysteine", "Tyrosine"}, + nil, + }, + { + "UGGAGAAUUAAUGGUUU", + []string{"Tryptophan"}, + ErrInvalidBase, + }, +} + +func TestProtein(t *testing.T) { + for _, test := range proteinTestCases { + actual, err := FromRNA(test.input) + if test.errorExpected != nil { + if test.errorExpected != err { + t.Fatalf("FAIL: RNA translation test: %s\nExpected error: %q\nActual error: %q", + test.input, test.errorExpected, err) + } + } else if err != nil { + t.Fatalf("FAIL: RNA translation test: %s\nExpected: %s\nGot error: %q", + test.input, test.expected, err) + } + if !reflect.DeepEqual(actual, test.expected) { + t.Fatalf("FAIL: RNA Translation test: %s\nExpected: %q\nActual %q", test.input, test.expected, actual) + } + t.Logf("PASS: RNA translation test: %s", test.input) + } +} + +func BenchmarkCodon(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + for _, test := range codonTestCases { + for i := 0; i < b.N; i++ { + FromCodon(test.input) + } + } +} + +func BenchmarkProtein(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + for _, test := range proteinTestCases { + for i := 0; i < b.N; i++ { + FromRNA(test.input) + } + } +} diff --git a/go/pythagorean-triplet/.exercism/config.json b/go/pythagorean-triplet/.exercism/config.json new file mode 100644 index 0000000..9180ff3 --- /dev/null +++ b/go/pythagorean-triplet/.exercism/config.json @@ -0,0 +1,32 @@ +{ + "blurb": "There exists exactly one Pythagorean triplet for which a + b + c = 1000. Find the product a * b * c.", + "authors": [ + "soniakeys" + ], + "contributors": [ + "alebaffa", + "bitfield", + "ekingery", + "ferhatelmas", + "hilary", + "kytrinyx", + "leenipper", + "petertseng", + "robphoenix", + "sebito91", + "tleen" + ], + "files": { + "solution": [ + "pythagorean_triplet.go" + ], + "test": [ + "pythagorean_triplet_test.go" + ], + "example": [ + ".meta/example.go" + ] + }, + "source": "Problem 9 at Project Euler", + "source_url": "http://projecteuler.net/problem=9" +} diff --git a/go/pythagorean-triplet/.exercism/metadata.json b/go/pythagorean-triplet/.exercism/metadata.json new file mode 100644 index 0000000..243914e --- /dev/null +++ b/go/pythagorean-triplet/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"pythagorean-triplet","id":"0e897c0fbe50436d8a7e3f121f06ac6d","url":"https://exercism.org/tracks/go/exercises/pythagorean-triplet","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/go/pythagorean-triplet/HELP.md b/go/pythagorean-triplet/HELP.md new file mode 100644 index 0000000..0db8d36 --- /dev/null +++ b/go/pythagorean-triplet/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit pythagorean_triplet.go` 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 [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/go/pythagorean-triplet/README.md b/go/pythagorean-triplet/README.md new file mode 100644 index 0000000..199c522 --- /dev/null +++ b/go/pythagorean-triplet/README.md @@ -0,0 +1,53 @@ +# Pythagorean Triplet + +Welcome to Pythagorean Triplet on Exercism's Go Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +A Pythagorean triplet is a set of three natural numbers, {a, b, c}, for +which, + +```text +a² + b² = c² +``` + +and such that, + +```text +a < b < c +``` + +For example, + +```text +3² + 4² = 9 + 16 = 25 = 5². +``` + +Given an input integer N, find all Pythagorean triplets for which `a + b + c = N`. + +For example, with N = 1000, there is exactly one Pythagorean triplet for which `a + b + c = 1000`: `{200, 375, 425}`. + +## Source + +### Created by + +- @soniakeys + +### Contributed to by + +- @alebaffa +- @bitfield +- @ekingery +- @ferhatelmas +- @hilary +- @kytrinyx +- @leenipper +- @petertseng +- @robphoenix +- @sebito91 +- @tleen + +### Based on + +Problem 9 at Project Euler - http://projecteuler.net/problem=9 \ No newline at end of file diff --git a/go/pythagorean-triplet/go.mod b/go/pythagorean-triplet/go.mod new file mode 100644 index 0000000..eae6521 --- /dev/null +++ b/go/pythagorean-triplet/go.mod @@ -0,0 +1,3 @@ +module pythagorean + +go 1.13 diff --git a/go/pythagorean-triplet/pythagorean_triplet.go b/go/pythagorean-triplet/pythagorean_triplet.go new file mode 100644 index 0000000..aacc6f2 --- /dev/null +++ b/go/pythagorean-triplet/pythagorean_triplet.go @@ -0,0 +1,39 @@ +package pythagorean + +import "math" + +type Triplet [3]int + +func isTriplet(a, b, c int) bool { + return a*a + b*b == c*c && a < b && b < c +} + +func Range(min, max int) []Triplet { + var triplets = []Triplet{} + for c := min; c <= max; c++ { + for b := min; b <= c - 1; b++ { + a := int(math.Sqrt(float64(c*c - b*b))) + + if isTriplet(a, b, c) && a >= min { + triplets = append(triplets, Triplet{a,b,c}) + } + } + } + return triplets +} + +func Sum(p int) []Triplet { + temp_triplets := Range(1, p / 2) + triplets := make([]Triplet, 0, len(temp_triplets)) + + for _, triplet := range temp_triplets { + if triplet[0] + triplet[1] + triplet[2] == p { + triplets = append(triplets, triplet) + } + } + // Reverse slice.. + for i, j := 0, len(triplets)-1; i < j; i, j = i+1, j-1 { + triplets[i], triplets[j] = triplets[j], triplets[i] + } + return triplets +} diff --git a/go/pythagorean-triplet/pythagorean_triplet_test.go b/go/pythagorean-triplet/pythagorean_triplet_test.go new file mode 100644 index 0000000..b62a845 --- /dev/null +++ b/go/pythagorean-triplet/pythagorean_triplet_test.go @@ -0,0 +1,60 @@ +package pythagorean + +import ( + "reflect" + "testing" +) + +var rangeTests = []struct { + min, max int + ts []Triplet +}{ + {1, 10, []Triplet{{3, 4, 5}, {6, 8, 10}}}, + {11, 20, []Triplet{{12, 16, 20}}}, +} + +func TestRange(t *testing.T) { + for _, test := range rangeTests { + ts := Range(test.min, test.max) + if !reflect.DeepEqual(ts, test.ts) { + t.Fatalf("Range(%d, %d) = %v, want %v", + test.min, test.max, ts, test.ts) + } + } +} + +var sumTests = []struct { + sum int + ts []Triplet +}{ + {180, []Triplet{{18, 80, 82}, {30, 72, 78}, {45, 60, 75}}}, + {1000, []Triplet{{200, 375, 425}}}, +} + +func TestSum(t *testing.T) { + for _, test := range sumTests { + ts := Sum(test.sum) + if !reflect.DeepEqual(ts, test.ts) { + t.Fatalf("Sum(%d) = %v, want %v", + test.sum, ts, test.ts) + } + } +} + +func BenchmarkRange(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + for i := 0; i < b.N; i++ { + Range(1, 100) + } +} + +func BenchmarkSum(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + for i := 0; i < b.N; i++ { + Sum(1000) + } +} diff --git a/go/run-length-encoding/.exercism/config.json b/go/run-length-encoding/.exercism/config.json new file mode 100644 index 0000000..b2f4ad3 --- /dev/null +++ b/go/run-length-encoding/.exercism/config.json @@ -0,0 +1,31 @@ +{ + "blurb": "Implement run-length encoding and decoding.", + "authors": [ + "MatForsberg" + ], + "contributors": [ + "bitfield", + "ekingery", + "ferhatelmas", + "hilary", + "ilmanzo", + "leenipper", + "sebito91" + ], + "files": { + "solution": [ + "run_length_encoding.go" + ], + "test": [ + "run_length_encoding_test.go" + ], + "example": [ + ".meta/example.go" + ], + "editor": [ + "cases_test.go" + ] + }, + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Run-length_encoding" +} diff --git a/go/run-length-encoding/.exercism/metadata.json b/go/run-length-encoding/.exercism/metadata.json new file mode 100644 index 0000000..a940dcd --- /dev/null +++ b/go/run-length-encoding/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"run-length-encoding","id":"c65b116f8aba4eaf9baa3b129a348992","url":"https://exercism.org/tracks/go/exercises/run-length-encoding","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/go/run-length-encoding/HELP.md b/go/run-length-encoding/HELP.md new file mode 100644 index 0000000..b38ebba --- /dev/null +++ b/go/run-length-encoding/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit run_length_encoding.go` 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 [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/go/run-length-encoding/README.md b/go/run-length-encoding/README.md new file mode 100644 index 0000000..778e641 --- /dev/null +++ b/go/run-length-encoding/README.md @@ -0,0 +1,49 @@ +# Run Length Encoding + +Welcome to Run Length Encoding on Exercism's Go Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +Implement run-length encoding and decoding. + +Run-length encoding (RLE) is a simple form of data compression, where runs +(consecutive data elements) are replaced by just one data value and count. + +For example we can represent the original 53 characters with only 13. + +```text +"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" -> "12WB12W3B24WB" +``` + +RLE allows the original data to be perfectly reconstructed from +the compressed data, which makes it a lossless data compression. + +```text +"AABCCCDEEEE" -> "2AB3CD4E" -> "AABCCCDEEEE" +``` + +For simplicity, you can assume that the unencoded string will only contain +the letters A through Z (either lower or upper case) and whitespace. This way +data to be encoded will never contain any numbers and numbers inside data to +be decoded always represent the count for the following character. + +## Source + +### Created by + +- @MatForsberg + +### Contributed to by + +- @bitfield +- @ekingery +- @ferhatelmas +- @hilary +- @ilmanzo +- @leenipper +- @sebito91 + +### Based on + +Wikipedia - https://en.wikipedia.org/wiki/Run-length_encoding \ No newline at end of file diff --git a/go/run-length-encoding/cases_test.go b/go/run-length-encoding/cases_test.go new file mode 100644 index 0000000..a8ccdb0 --- /dev/null +++ b/go/run-length-encoding/cases_test.go @@ -0,0 +1,42 @@ +package encode + +// Source: exercism/problem-specifications +// Commit: 1b7900e run-length-encoding: apply "input" policy +// Problem Specifications Version: 1.1.0 + +// run-length encode a string +var encodeTests = []struct { + input string + expected string + description string +}{ + {"", "", "empty string"}, + {"XYZ", "XYZ", "single characters only are encoded without count"}, + {"AABBBCCCC", "2A3B4C", "string with no single characters"}, + {"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB", "12WB12W3B24WB", "single characters mixed with repeated characters"}, + {" hsqq qww ", "2 hs2q q2w2 ", "multiple whitespace mixed in string"}, + {"aabbbcccc", "2a3b4c", "lowercase characters"}, +} + +// run-length decode a string +var decodeTests = []struct { + input string + expected string + description string +}{ + {"", "", "empty string"}, + {"XYZ", "XYZ", "single characters only"}, + {"2A3B4C", "AABBBCCCC", "string with no single characters"}, + {"12WB12W3B24WB", "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB", "single characters with repeated characters"}, + {"2 hs2q q2w2 ", " hsqq qww ", "multiple whitespace mixed in string"}, + {"2a3b4c", "aabbbcccc", "lower case string"}, +} + +// encode and then decode +var encodeDecodeTests = []struct { + input string + expected string + description string +}{ + {"zzz ZZ zZ", "zzz ZZ zZ", "encode followed by decode gives original string"}, +} diff --git a/go/run-length-encoding/go.mod b/go/run-length-encoding/go.mod new file mode 100644 index 0000000..95a4869 --- /dev/null +++ b/go/run-length-encoding/go.mod @@ -0,0 +1,3 @@ +module encode + +go 1.13 diff --git a/go/run-length-encoding/run_length_encoding.go b/go/run-length-encoding/run_length_encoding.go new file mode 100644 index 0000000..110b341 --- /dev/null +++ b/go/run-length-encoding/run_length_encoding.go @@ -0,0 +1,9 @@ +package encode + +func RunLengthEncode(input string) string { + panic("Please implement the RunLengthEncode function") +} + +func RunLengthDecode(input string) string { + panic("Please implement the RunLengthDecode function") +} diff --git a/go/run-length-encoding/run_length_encoding_test.go b/go/run-length-encoding/run_length_encoding_test.go new file mode 100644 index 0000000..d5be01f --- /dev/null +++ b/go/run-length-encoding/run_length_encoding_test.go @@ -0,0 +1,31 @@ +package encode + +import "testing" + +func TestRunLengthEncode(t *testing.T) { + for _, test := range encodeTests { + if actual := RunLengthEncode(test.input); actual != test.expected { + t.Errorf("FAIL %s - RunLengthEncode(%s) = %q, expected %q.", + test.description, test.input, actual, test.expected) + } + t.Logf("PASS RunLengthEncode - %s", test.description) + } +} +func TestRunLengthDecode(t *testing.T) { + for _, test := range decodeTests { + if actual := RunLengthDecode(test.input); actual != test.expected { + t.Errorf("FAIL %s - RunLengthDecode(%s) = %q, expected %q.", + test.description, test.input, actual, test.expected) + } + t.Logf("PASS RunLengthDecode - %s", test.description) + } +} +func TestRunLengthEncodeDecode(t *testing.T) { + for _, test := range encodeDecodeTests { + if actual := RunLengthDecode(RunLengthEncode(test.input)); actual != test.expected { + t.Errorf("FAIL %s - RunLengthDecode(RunLengthEncode(%s)) = %q, expected %q.", + test.description, test.input, actual, test.expected) + } + t.Logf("PASS %s", test.description) + } +} diff --git a/go/tournament/.exercism/config.json b/go/tournament/.exercism/config.json new file mode 100644 index 0000000..e7371eb --- /dev/null +++ b/go/tournament/.exercism/config.json @@ -0,0 +1,32 @@ +{ + "blurb": "Tally the results of a small football competition.", + "authors": [ + "pminten" + ], + "contributors": [ + "alebaffa", + "bitfield", + "ekingery", + "ferhatelmas", + "hilary", + "kytrinyx", + "leenipper", + "manavo", + "petertseng", + "robphoenix", + "sebito91", + "soniakeys", + "tleen" + ], + "files": { + "solution": [ + "tournament.go" + ], + "test": [ + "tournament_test.go" + ], + "example": [ + ".meta/example.go" + ] + } +} diff --git a/go/tournament/.exercism/metadata.json b/go/tournament/.exercism/metadata.json new file mode 100644 index 0000000..8a27552 --- /dev/null +++ b/go/tournament/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"tournament","id":"399ebb8ad6844f9f986ef2e70737b8fa","url":"https://exercism.org/tracks/go/exercises/tournament","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/go/tournament/HELP.md b/go/tournament/HELP.md new file mode 100644 index 0000000..3f1c2ce --- /dev/null +++ b/go/tournament/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit tournament.go` 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 [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/go/tournament/README.md b/go/tournament/README.md new file mode 100644 index 0000000..fc2ca0d --- /dev/null +++ b/go/tournament/README.md @@ -0,0 +1,90 @@ +# Tournament + +Welcome to Tournament on Exercism's Go Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +Tally the results of a small football competition. + +Based on an input file containing which team played against which and what the +outcome was, create a file with a table like this: + +```text +Team | MP | W | D | L | P +Devastating Donkeys | 3 | 2 | 1 | 0 | 7 +Allegoric Alaskans | 3 | 2 | 0 | 1 | 6 +Blithering Badgers | 3 | 1 | 0 | 2 | 3 +Courageous Californians | 3 | 0 | 1 | 2 | 1 +``` + +What do those abbreviations mean? + +- MP: Matches Played +- W: Matches Won +- D: Matches Drawn (Tied) +- L: Matches Lost +- P: Points + +A win earns a team 3 points. A draw earns 1. A loss earns 0. + +The outcome should be ordered by points, descending. In case of a tie, teams are ordered alphabetically. + +## Input + +Your tallying program will receive input that looks like: + +```text +Allegoric Alaskans;Blithering Badgers;win +Devastating Donkeys;Courageous Californians;draw +Devastating Donkeys;Allegoric Alaskans;win +Courageous Californians;Blithering Badgers;loss +Blithering Badgers;Devastating Donkeys;loss +Allegoric Alaskans;Courageous Californians;win +``` + +The result of the match refers to the first team listed. So this line: + +```text +Allegoric Alaskans;Blithering Badgers;win +``` + +means that the Allegoric Alaskans beat the Blithering Badgers. + +This line: + +```text +Courageous Californians;Blithering Badgers;loss +``` + +means that the Blithering Badgers beat the Courageous Californians. + +And this line: + +```text +Devastating Donkeys;Courageous Californians;draw +``` + +means that the Devastating Donkeys and Courageous Californians tied. + +## Source + +### Created by + +- @pminten + +### Contributed to by + +- @alebaffa +- @bitfield +- @ekingery +- @ferhatelmas +- @hilary +- @kytrinyx +- @leenipper +- @manavo +- @petertseng +- @robphoenix +- @sebito91 +- @soniakeys +- @tleen \ No newline at end of file diff --git a/go/tournament/go.mod b/go/tournament/go.mod new file mode 100644 index 0000000..e4576f2 --- /dev/null +++ b/go/tournament/go.mod @@ -0,0 +1,5 @@ +module tournament + +go 1.13 + +require golang.org/x/tools v0.1.7 // indirect diff --git a/go/tournament/go.sum b/go/tournament/go.sum new file mode 100644 index 0000000..f8603d7 --- /dev/null +++ b/go/tournament/go.sum @@ -0,0 +1,33 @@ +github.com/yuin/goldmark v1.4.0 h1:OtISOGfH6sOWa1/qXqqAiOIAO6Z5J3AEAE18WAq6BiQ= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d h1:20cMwl2fHAzkJMEA+8J4JgqBQcQGzbisXo31MIeenXI= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/go/tournament/tournament.go b/go/tournament/tournament.go new file mode 100644 index 0000000..aee65a8 --- /dev/null +++ b/go/tournament/tournament.go @@ -0,0 +1,23 @@ +package tournament + +import ( + "errors" + "strings" + "io" +) +func Tally(in io.Reader, out io.Writer) error { + buf := new(strings.Builder) + _, err := io.Copy(buf, in) + if err != nil { + return err + } + s := buf.String() + lines := strings.Split(s, "\n") + + for _, line := range lines { + if strings.HasPrefix(line, "#") || len(line) == 0 { + continue + } + } + return errors.New("foo") +} diff --git a/go/tournament/tournament_test.go b/go/tournament/tournament_test.go new file mode 100644 index 0000000..67477a2 --- /dev/null +++ b/go/tournament/tournament_test.go @@ -0,0 +1,152 @@ +package tournament + +import ( + "bytes" + "io" + "strings" + "testing" +) + +// Define a function Tally(io.Reader, io.Writer) error. +// +// Note that unlike other tracks the Go version of the tally function +// should not ignore errors. It's not idiomatic Go to ignore errors. + +var _ func(io.Reader, io.Writer) error = Tally + +// These test what testers call the happy path, where there's no error. +var happyTestCases = []struct { + description string + input string + expected string +}{ + { + description: "good", + input: ` +Allegoric Alaskians;Blithering Badgers;win +Devastating Donkeys;Courageous Californians;draw +Devastating Donkeys;Allegoric Alaskians;win +Courageous Californians;Blithering Badgers;loss +Blithering Badgers;Devastating Donkeys;loss +Allegoric Alaskians;Courageous Californians;win +`, + expected: ` +Team | MP | W | D | L | P +Devastating Donkeys | 3 | 2 | 1 | 0 | 7 +Allegoric Alaskians | 3 | 2 | 0 | 1 | 6 +Blithering Badgers | 3 | 1 | 0 | 2 | 3 +Courageous Californians | 3 | 0 | 1 | 2 | 1 +`[1:], // [1:] = strip initial readability newline + }, + { + description: "ignore comments and newlines", + input: ` + +Allegoric Alaskians;Blithering Badgers;win +Devastating Donkeys;Allegoric Alaskians;win +# Catastrophic Loss of the Californians +Courageous Californians;Blithering Badgers;loss + +Blithering Badgers;Devastating Donkeys;loss +Allegoric Alaskians;Courageous Californians;win +Devastating Donkeys;Courageous Californians;draw + + +`, + expected: ` +Team | MP | W | D | L | P +Devastating Donkeys | 3 | 2 | 1 | 0 | 7 +Allegoric Alaskians | 3 | 2 | 0 | 1 | 6 +Blithering Badgers | 3 | 1 | 0 | 2 | 3 +Courageous Californians | 3 | 0 | 1 | 2 | 1 +`[1:], + }, + { + // A complete competition has all teams play eachother once or twice. + description: "incomplete competition", + input: ` +Allegoric Alaskians;Blithering Badgers;win +Devastating Donkeys;Allegoric Alaskians;win +Courageous Californians;Blithering Badgers;loss +Allegoric Alaskians;Courageous Californians;win +`, + expected: ` +Team | MP | W | D | L | P +Allegoric Alaskians | 3 | 2 | 0 | 1 | 6 +Blithering Badgers | 2 | 1 | 0 | 1 | 3 +Devastating Donkeys | 1 | 1 | 0 | 0 | 3 +Courageous Californians | 2 | 0 | 0 | 2 | 0 +`[1:], + }, + { + description: "tie for first and last place", + input: ` +Courageous Californians;Devastating Donkeys;win +Allegoric Alaskians;Blithering Badgers;win +Devastating Donkeys;Allegoric Alaskians;loss +Courageous Californians;Blithering Badgers;win +Blithering Badgers;Devastating Donkeys;draw +Allegoric Alaskians;Courageous Californians;draw +`, + expected: ` +Team | MP | W | D | L | P +Allegoric Alaskians | 3 | 2 | 1 | 0 | 7 +Courageous Californians | 3 | 2 | 1 | 0 | 7 +Blithering Badgers | 3 | 0 | 1 | 2 | 1 +Devastating Donkeys | 3 | 0 | 1 | 2 | 1 +`[1:], + }, +} + +var errorTestCases = []string{ + "Bla;Bla;Bla", + "Devastating Donkeys_Courageous Californians;draw", + "Devastating Donkeys@Courageous Californians;draw", + "Devastating Donkeys;Allegoric Alaskians;dra", +} + +func TestTallyHappy(t *testing.T) { + for _, tt := range happyTestCases { + reader := strings.NewReader(tt.input) + var buffer bytes.Buffer + err := Tally(reader, &buffer) + actual := buffer.String() + // We don't expect errors for any of the test cases + if err != nil { + t.Fatalf("Tally for input named %q returned error %q. Error not expected.", + tt.description, err) + } + if actual != tt.expected { + t.Fatalf("Tally for input named %q was expected to return...\n%s\n...but returned...\n%s", + tt.description, tt.expected, actual) + } + } +} + +func TestTallyError(t *testing.T) { + for _, s := range errorTestCases { + reader := strings.NewReader(s) + var buffer bytes.Buffer + err := Tally(reader, &buffer) + if err == nil { + t.Fatalf("Tally for input %q should have failed but didn't.", s) + } + var _ error = err + } +} + +func BenchmarkTally(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + for i := 0; i < b.N; i++ { + for _, tt := range happyTestCases { + var buffer bytes.Buffer + Tally(strings.NewReader(tt.input), &buffer) + } + for _, s := range errorTestCases { + var buffer bytes.Buffer + Tally(strings.NewReader(s), &buffer) + } + } +} diff --git a/go/tree-building/.exercism/config.json b/go/tree-building/.exercism/config.json new file mode 100644 index 0000000..8fce632 --- /dev/null +++ b/go/tree-building/.exercism/config.json @@ -0,0 +1,37 @@ +{ + "blurb": "Refactor a tree building algorithm.", + "authors": [ + "pminten" + ], + "contributors": [ + "alebaffa", + "bitfield", + "Daveed9", + "devillexio", + "dvrkps", + "ekingery", + "ferhatelmas", + "hilary", + "jeffguorg", + "kytrinyx", + "leenipper", + "object88", + "petertseng", + "robphoenix", + "sebito91", + "soniakeys", + "tbrisker", + "tleen" + ], + "files": { + "solution": [ + "tree_building.go" + ], + "test": [ + "tree_building_test.go" + ], + "example": [ + ".meta/example.go" + ] + } +} diff --git a/go/tree-building/.exercism/metadata.json b/go/tree-building/.exercism/metadata.json new file mode 100644 index 0000000..aacee4e --- /dev/null +++ b/go/tree-building/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"tree-building","id":"41954e1ca66440f899c639278975f0d2","url":"https://exercism.org/tracks/go/exercises/tree-building","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/go/tree-building/HELP.md b/go/tree-building/HELP.md new file mode 100644 index 0000000..404a81b --- /dev/null +++ b/go/tree-building/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit tree_building.go` 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 [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/go/tree-building/README.md b/go/tree-building/README.md new file mode 100644 index 0000000..3f2c9d7 --- /dev/null +++ b/go/tree-building/README.md @@ -0,0 +1,56 @@ +# Tree Building + +Welcome to Tree Building on Exercism's Go Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +Some web-forums have a tree layout, so posts are presented as a tree. However +the posts are typically stored in a database as an unsorted set of records. Thus +when presenting the posts to the user the tree structure has to be +reconstructed. + +Your job will be to implement the tree building logic for these records. The +records only contain an ID number and a parent ID number. The ID number is +always between 0 (inclusive) and the length of the record list (exclusive). All +records have a parent ID lower than their own ID, except for the root record, +which has a parent ID that's equal to its own ID. + +An example tree: + +```text +root (ID: 0, parent ID: 0) +|-- child1 (ID: 1, parent ID: 0) +| |-- grandchild1 (ID: 2, parent ID: 1) +| +-- grandchild2 (ID: 4, parent ID: 1) ++-- child2 (ID: 3, parent ID: 0) +| +-- grandchild3 (ID: 6, parent ID: 3) ++-- child3 (ID: 5, parent ID: 0) +``` + +## Source + +### Created by + +- @pminten + +### Contributed to by + +- @alebaffa +- @bitfield +- @Daveed9 +- @devillexio +- @dvrkps +- @ekingery +- @ferhatelmas +- @hilary +- @jeffguorg +- @kytrinyx +- @leenipper +- @object88 +- @petertseng +- @robphoenix +- @sebito91 +- @soniakeys +- @tbrisker +- @tleen \ No newline at end of file diff --git a/go/tree-building/go.mod b/go/tree-building/go.mod new file mode 100644 index 0000000..8f71236 --- /dev/null +++ b/go/tree-building/go.mod @@ -0,0 +1,3 @@ +module tree + +go 1.13 diff --git a/go/tree-building/tree_building.go b/go/tree-building/tree_building.go new file mode 100644 index 0000000..ee759f3 --- /dev/null +++ b/go/tree-building/tree_building.go @@ -0,0 +1,12 @@ +package tree + +// Define the Record type +struct Node { + +} + +// Define the Node type + +func Build(records []Record) (*Node, error) { + panic("Please implement the Build function") +} diff --git a/go/tree-building/tree_building_test.go b/go/tree-building/tree_building_test.go new file mode 100644 index 0000000..226a6b9 --- /dev/null +++ b/go/tree-building/tree_building_test.go @@ -0,0 +1,351 @@ +package tree + +import ( + "fmt" + "math/rand" + "reflect" + "testing" +) + +// Define a function Build(records []Record) (*Node, error) +// where Record is a struct containing int fields ID and Parent +// and Node is a struct containing int field ID and []*Node field Children. + +var successTestCases = []struct { + name string + input []Record + expected *Node +}{ + { + name: "empty input", + input: []Record{}, + expected: nil, + }, + { + name: "one node", + input: []Record{ + {ID: 0}, + }, + expected: &Node{ + ID: 0, + }, + }, + { + name: "three nodes in order", + input: []Record{ + {ID: 0}, + {ID: 1, Parent: 0}, + {ID: 2, Parent: 0}, + }, + expected: &Node{ + ID: 0, + Children: []*Node{ + {ID: 1}, + {ID: 2}, + }, + }, + }, + { + name: "three nodes in reverse order", + input: []Record{ + {ID: 2, Parent: 0}, + {ID: 1, Parent: 0}, + {ID: 0}, + }, + expected: &Node{ + ID: 0, + Children: []*Node{ + {ID: 1}, + {ID: 2}, + }, + }, + }, + { + name: "three levels of nesting", + input: []Record{ + {ID: 2, Parent: 1}, + {ID: 1, Parent: 0}, + {ID: 3, Parent: 2}, + {ID: 0}, + }, + expected: &Node{ + ID: 0, + Children: []*Node{ + { + ID: 1, + Children: []*Node{ + { + ID: 2, + Children: []*Node{ + {ID: 3}, + }, + }, + }, + }, + }, + }, + }, + { + name: "more than two children", + input: []Record{ + {ID: 3, Parent: 0}, + {ID: 2, Parent: 0}, + {ID: 1, Parent: 0}, + {ID: 0}, + }, + expected: &Node{ + ID: 0, + Children: []*Node{ + {ID: 1}, + {ID: 2}, + {ID: 3}, + }, + }, + }, + { + name: "binary tree", + input: []Record{ + {ID: 5, Parent: 1}, + {ID: 3, Parent: 2}, + {ID: 2, Parent: 0}, + {ID: 4, Parent: 1}, + {ID: 1, Parent: 0}, + {ID: 0}, + {ID: 6, Parent: 2}, + }, + expected: &Node{ + ID: 0, + Children: []*Node{ + { + ID: 1, + Children: []*Node{ + {ID: 4}, + {ID: 5}, + }, + }, + { + ID: 2, + Children: []*Node{ + {ID: 3}, + {ID: 6}, + }, + }, + }, + }, + }, + { + name: "unbalanced tree", + input: []Record{ + {ID: 5, Parent: 2}, + {ID: 3, Parent: 2}, + {ID: 2, Parent: 0}, + {ID: 4, Parent: 1}, + {ID: 1, Parent: 0}, + {ID: 0}, + {ID: 6, Parent: 2}, + }, + expected: &Node{ + ID: 0, + Children: []*Node{ + { + ID: 1, + Children: []*Node{ + {ID: 4}, + }, + }, + { + ID: 2, + Children: []*Node{ + {ID: 3}, + {ID: 5}, + {ID: 6}, + }, + }, + }, + }, + }, +} + +var failureTestCases = []struct { + name string + input []Record +}{ + { + name: "root node has parent", + input: []Record{ + {ID: 0, Parent: 1}, + {ID: 1, Parent: 0}, + }, + }, + { + name: "no root node", + input: []Record{ + {ID: 1, Parent: 0}, + }, + }, + { + name: "duplicate node", + input: []Record{ + {ID: 0, Parent: 0}, + {ID: 1, Parent: 0}, + {ID: 1, Parent: 0}, + }, + }, + { + name: "duplicate root", + input: []Record{ + {ID: 0, Parent: 0}, + {ID: 0, Parent: 0}, + }, + }, + { + name: "non-continuous", + input: []Record{ + {ID: 2, Parent: 0}, + {ID: 4, Parent: 2}, + {ID: 1, Parent: 0}, + {ID: 0}, + }, + }, + { + name: "cycle directly", + input: []Record{ + {ID: 5, Parent: 2}, + {ID: 3, Parent: 2}, + {ID: 2, Parent: 2}, + {ID: 4, Parent: 1}, + {ID: 1, Parent: 0}, + {ID: 0}, + {ID: 6, Parent: 3}, + }, + }, + { + name: "cycle indirectly", + input: []Record{ + {ID: 5, Parent: 2}, + {ID: 3, Parent: 2}, + {ID: 2, Parent: 6}, + {ID: 4, Parent: 1}, + {ID: 1, Parent: 0}, + {ID: 0}, + {ID: 6, Parent: 3}, + }, + }, + { + name: "higher id parent of lower id", + input: []Record{ + {ID: 0}, + {ID: 2, Parent: 0}, + {ID: 1, Parent: 2}, + }, + }, +} + +func (n Node) String() string { + return fmt.Sprintf("%d:%s", n.ID, n.Children) +} + +func TestMakeTreeSuccess(t *testing.T) { + for _, tt := range successTestCases { + t.Run(tt.name, func(t *testing.T) { + actual, err := Build(tt.input) + if err != nil { + var _ error = err + t.Fatalf("Build for test case %q returned error %q. Error not expected.", + tt.name, err) + } + if !reflect.DeepEqual(actual, tt.expected) { + t.Fatalf("Build for test case %q returned %s but was expected to return %s.", + tt.name, actual, tt.expected) + } + }) + } +} + +func TestMakeTreeFailure(t *testing.T) { + for _, tt := range failureTestCases { + t.Run(tt.name, func(t *testing.T) { + actual, err := Build(tt.input) + if err == nil { + t.Fatalf("Build for test case %q returned %s but was expected to fail.", + tt.name, actual) + } + }) + } +} + +func shuffleRecords(records []Record) []Record { + gen := rand.New(rand.NewSource(42)) + newRecords := make([]Record, len(records)) + for i, idx := range gen.Perm(len(records)) { + newRecords[i] = records[idx] + } + return newRecords +} + +// Binary tree +func makeTwoTreeRecords() []Record { + records := make([]Record, 1<<16) + for i := range records { + if i == 0 { + records[i] = Record{ID: 0} + } else { + records[i] = Record{ID: i, Parent: i >> 1} + } + } + return shuffleRecords(records) +} + +var twoTreeRecords = makeTwoTreeRecords() + +func BenchmarkTwoTree(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + for i := 0; i < b.N; i++ { + Build(twoTreeRecords) + } +} + +// Each node but the root node and leaf nodes has ten children. +func makeTenTreeRecords() []Record { + records := make([]Record, 10000) + for i := range records { + if i == 0 { + records[i] = Record{ID: 0} + } else { + records[i] = Record{ID: i, Parent: i / 10} + } + } + return shuffleRecords(records) +} + +var tenTreeRecords = makeTenTreeRecords() + +func BenchmarkTenTree(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + for i := 0; i < b.N; i++ { + Build(tenTreeRecords) + } +} + +func makeShallowRecords() []Record { + records := make([]Record, 10000) + for i := range records { + records[i] = Record{ID: i, Parent: 0} + } + return shuffleRecords(records) +} + +var shallowRecords = makeShallowRecords() + +func BenchmarkShallowTree(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + for i := 0; i < b.N; i++ { + Build(shallowRecords) + } +} diff --git a/go/weather-forecast/.exercism/config.json b/go/weather-forecast/.exercism/config.json new file mode 100644 index 0000000..04e5079 --- /dev/null +++ b/go/weather-forecast/.exercism/config.json @@ -0,0 +1,18 @@ +{ + "blurb": "Learn about comments by helping a weather station manage their weather forecasting program.", + "authors": [ + "nikimanoledaki", + "micuffaro" + ], + "files": { + "solution": [ + "weather_forecast.go" + ], + "test": [ + "weather_forecast_test.go" + ], + "exemplar": [ + ".meta/exemplar.go" + ] + } +} diff --git a/go/weather-forecast/.exercism/metadata.json b/go/weather-forecast/.exercism/metadata.json new file mode 100644 index 0000000..aa28656 --- /dev/null +++ b/go/weather-forecast/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"weather-forecast","id":"dae1e70ff5084621a4cc1bb59d66a239","url":"https://exercism.org/tracks/go/exercises/weather-forecast","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/go/weather-forecast/HELP.md b/go/weather-forecast/HELP.md new file mode 100644 index 0000000..68e3b3e --- /dev/null +++ b/go/weather-forecast/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit weather_forecast.go` 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 [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/go/weather-forecast/HINTS.md b/go/weather-forecast/HINTS.md new file mode 100644 index 0000000..d37481d --- /dev/null +++ b/go/weather-forecast/HINTS.md @@ -0,0 +1,24 @@ +# Hints + +## General + +- A [documentation comment][comment] should be written directly before the entity that it is describing, start with the name of what it is describing, take the form of a sentence, and end with a period. + +## 1. Document package weather + +- The [package comment][comment] should be written directly before the package, start with `Package x`, and end with a period. + +## 2. Document the CurrentCondition variable + +- The [variable comment][variable comment] should be written right before the variable that it is describing, start with its name, and end with a period. + +## 3. Document the CurrentLocation variable + +- The [variable comment][variable comment] should be written right before the variable that it is describing, start with its name, and end with a period. + +## 4. Document the Forecast() function + +- The [function comment][comment] should come directly before the function, start with the name of the function and end with a period. + +[comment]: https://golang.org/doc/effective_go.html#commentary +[variable comment]: https://dave.cheney.net/practical-go/presentations/qcon-china.html#_comments \ No newline at end of file diff --git a/go/weather-forecast/README.md b/go/weather-forecast/README.md new file mode 100644 index 0000000..450e18b --- /dev/null +++ b/go/weather-forecast/README.md @@ -0,0 +1,72 @@ +# Weather Forecast + +Welcome to Weather Forecast on Exercism's Go 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 + +In the previous exercise, we saw that there are two ways to write comments in Go: single-line comments that are preceded by `//`, and multiline comment blocks that are wrapped with `/*` and `*/`. + +## Documentation comments + +In Go, comments play an important role in documenting code. They are used by the `godoc` command, which extracts these comments to create documentation about Go packages. A documentation comment should be a complete sentence that starts with the name of the thing being described and ends with a period. + +Comments should precede packages as well as exported identifiers, for example exported functions, methods, package variables, constants, and structs, which you will learn more about in the next exercises. + +A package-level variable can look like this: + +```go +// TemperatureCelsius represents a certain temperature in degrees Celsius. +var TemperatureCelsius float64 +``` + +## Package comments + +Package comments should be written directly before a package clause (`package x`) and begin with `Package x ...` like this: + +```go +// Package kelvin provides tools to convert +// temperatures to and from Kelvin. +package kelvin +``` + +## Function comments + +A function comment should be written directly before the function declaration. It should be a full sentence that starts with the function name. For example, an exported comment for the function `Calculate` should take the form `Calculate ...`. It should also explain what arguments the function takes, what it does with them, and what its return values mean, ending in a period): + +```go +// CelsiusFreezingTemp returns an integer value equal to the temperature at which water freezes in degrees Celsius. +func CelsiusFreezingTemp() int { + return 0 +} +``` + +## Instructions + +In this exercise, your task is to help a weather station manage their weather forecasting program. + +## 1. Document package weather + +Write a package comment for `package weather` that describes its contents. + +## 2. Document the CurrentCondition variable + +Write a comment for the package variable `CurrentCondition`. + +This should tell any user of the package what information the variable stores, and what they can do with it. + +## 3. Document the CurrentLocation variable + +Just like the previous step, write a comment for `CurrentLocation`. + +## 4. Document the Forecast() function + +Write a function comment for `Forecast()`. + +## Source + +### Created by + +- @nikimanoledaki +- @micuffaro \ No newline at end of file diff --git a/go/weather-forecast/go.mod b/go/weather-forecast/go.mod new file mode 100644 index 0000000..1c22377 --- /dev/null +++ b/go/weather-forecast/go.mod @@ -0,0 +1,3 @@ +module weather + +go 1.16 \ No newline at end of file diff --git a/go/weather-forecast/weather_forecast.go b/go/weather-forecast/weather_forecast.go new file mode 100644 index 0000000..0073ecf --- /dev/null +++ b/go/weather-forecast/weather_forecast.go @@ -0,0 +1,13 @@ +// Package weather contains functions for forecasting the weather at a given location. +package weather + +// CurrentCondition stores the current weather condition. +var CurrentCondition string +// CurrentLocation stores the current location for the weather forecast. +var CurrentLocation string + +// Forecast takes a city and location as an argument and returns the current weather condition. +func Forecast(city, condition string) string { + CurrentLocation, CurrentCondition = city, condition + return CurrentLocation + " - current weather condition: " + CurrentCondition +} diff --git a/go/weather-forecast/weather_forecast_test.go b/go/weather-forecast/weather_forecast_test.go new file mode 100644 index 0000000..f6a1883 --- /dev/null +++ b/go/weather-forecast/weather_forecast_test.go @@ -0,0 +1,140 @@ +package weather + +import ( + "fmt" + "go/ast" + "go/parser" + "go/token" + "strings" + "testing" +) + +func TestComments(t *testing.T) { + filename := "weather_forecast.go" + + fs := token.NewFileSet() + f, err := parser.ParseFile(fs, filename, nil, parser.ParseComments) + if err != nil { + t.Fatal(err) + } + + wantedComments := 4 + got := len(f.Comments) + if got != wantedComments { + t.Errorf("Incorrect number of comments: got %d, want %d", got, wantedComments) + } + + testPackageComment(t, f) + + ast.Inspect(f, func(node ast.Node) bool { + switch n := node.(type) { + case *ast.GenDecl: + if n.Lparen.IsValid() { + for _, v := range n.Specs { + testBlockIdentifierComment(t, v.(*ast.ValueSpec)) + } + } else { + testIdentifierComment(t, n) + } + case *ast.FuncDecl: + testFunctionComment(t, n) + } + return true + }) +} + +func testPackageComment(t *testing.T, node *ast.File) { + t.Helper() + if node.Doc == nil { + t.Errorf("Package weather should have a comment") + } + + packageName := node.Name.Name + want := "Package " + packageName + packageComment := node.Doc.Text() + + if ok, errStr := testComment("Package", packageName, packageComment, want); !ok { + t.Error(errStr) + } + +} +func testIdentifierComment(t *testing.T, node *ast.GenDecl) { + t.Helper() + + identifierName := node.Specs[0].(*ast.ValueSpec).Names[0].Name + if node.Doc == nil { + t.Errorf("Exported identifier %s should have a comment", identifierName) + } + + identifierComment := node.Doc.Text() + want := identifierName + + if ok, errStr := testComment("Variable", identifierName, identifierComment, want); !ok { + t.Error(errStr) + } +} + +func testBlockIdentifierComment(t *testing.T, node *ast.ValueSpec) { + t.Helper() + + identifierName := node.Names[0].Name + if node.Doc == nil { + t.Errorf("Exported identifier %s should have a comment", identifierName) + } + + identifierComment := node.Doc.Text() + want := identifierName + + if ok, errStr := testComment("Variable", identifierName, identifierComment, want); !ok { + t.Error(errStr) + } + +} + +func testFunctionComment(t *testing.T, node *ast.FuncDecl) { + t.Helper() + funcName := node.Name.Name + if node.Doc == nil { + t.Errorf("Exported function %s() should have a comment", funcName) + } + + funcComment := node.Doc.Text() + want := funcName + + if ok, errStr := testComment("Function", funcName, funcComment, want); !ok { + t.Error(errStr) + } +} + +func testComment(entityKind, entityName, comment, wantedPrefix string) (ok bool, errString string) { + + trimmedComment := strings.TrimSpace(comment) + lowerEntity := strings.ToLower(entityKind) + + // Check if comment has wanted prefix + if !strings.HasPrefix(comment, wantedPrefix) { + errorString := fmt.Sprintf("%s comment for %s '%s' should start with '// %s ...': got '// %s'", + entityKind, lowerEntity, entityName, wantedPrefix, trimmedComment) + return false, errorString + } + + // Check if comment content is empty + commentContent := strings.TrimPrefix(trimmedComment, wantedPrefix) + commentContent = strings.TrimSpace(commentContent) + commentContent = strings.TrimSuffix(commentContent, ".") + + if commentContent == "" { + lowerEntity := strings.ToLower(entityKind) + errorString := fmt.Sprintf("%s comment of '%s' should provide a description of the %s, e.g '// %s <%s_description>'", + entityKind, entityName, lowerEntity, wantedPrefix, lowerEntity) + return false, errorString + } + + // Check if comment ends in a period + if !strings.HasSuffix(trimmedComment, ".") { + return false, fmt.Sprintf("%s comment for %s '%s' should end with a period (.)", + entityKind, lowerEntity, entityName) + } + + return true, "" +} diff --git a/julia/binary-search/.exercism/metadata.json b/julia/binary-search/.exercism/metadata.json new file mode 100644 index 0000000..844169b --- /dev/null +++ b/julia/binary-search/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"julia","exercise":"binary-search","id":"ce0cd3b336094a49af31b3ed09f02bee","url":"https://exercism.io/my/solutions/ce0cd3b336094a49af31b3ed09f02bee","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/julia/binary-search/README.md b/julia/binary-search/README.md new file mode 100644 index 0000000..9ddc31d --- /dev/null +++ b/julia/binary-search/README.md @@ -0,0 +1,51 @@ +# Binary Search + +Implement a binary search algorithm. + +Searching a sorted collection is a common task. A dictionary is a sorted +list of word definitions. Given a word, one can find its definition. A +telephone book is a sorted list of people's names, addresses, and +telephone numbers. Knowing someone's name allows one to quickly find +their telephone number and address. + +If the list to be searched contains more than a few items (a dozen, say) +a binary search will require far fewer comparisons than a linear search, +but it imposes the requirement that the list be sorted. + +In computer science, a binary search or half-interval search algorithm +finds the position of a specified input value (the search "key") within +an array sorted by key value. + +In each step, the algorithm compares the search key value with the key +value of the middle element of the array. + +If the keys match, then a matching element has been found and the range of indices that equal the search key value are returned. + +Otherwise, if the search key is less than the middle element's key, then +the algorithm repeats its action on the sub-array to the left of the +middle element or, if the search key is greater, on the sub-array to the +right. + +If the remaining array to be searched is empty, then the key cannot be +found in the array and a special "not found" indication is returned. Search methods in Julia typically return an empty range located at the insertion point in this case. + +A binary search halves the number of items to check with each iteration, +so locating an item (or determining its absence) takes logarithmic time. +A binary search is a dichotomic divide and conquer search algorithm. + +**For simplification, you can assume that all elements of the list to be searched are unique.** Feel free to implement a solution that works on lists with non-unique elements as a bonus task. + +## Bonus task +Implement keyword arguments `by`, `lt` and `rev` so that `by` specifies a transformation applied to all elements of the list, `lt` specifies a comparison and `rev` specifies if the list is ordered in reverse. + +## Source + +Wikipedia [http://en.wikipedia.org/wiki/Binary_search_algorithm](http://en.wikipedia.org/wiki/Binary_search_algorithm) + +Some phrases above and the bonus tasks are taken from the [Julia base documentation (MIT license)](https://docs.julialang.org/en/v1/base/sort/#Base.Sort.searchsorted) of `searchsorted`. + +## Version compatibility +This exercise has been tested on Julia versions >=1.0. + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/julia/binary-search/binary-search.ipynb b/julia/binary-search/binary-search.ipynb new file mode 100644 index 0000000..dc6ce71 --- /dev/null +++ b/julia/binary-search/binary-search.ipynb @@ -0,0 +1,68 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": ["# Binary Search\n", "\n", "Implement a binary search algorithm.\n", "\n", "Searching a sorted collection is a common task. A dictionary is a sorted\n", "list of word definitions. Given a word, one can find its definition. A\n", "telephone book is a sorted list of people's names, addresses, and\n", "telephone numbers. Knowing someone's name allows one to quickly find\n", "their telephone number and address.\n", "\n", "If the list to be searched contains more than a few items (a dozen, say)\n", "a binary search will require far fewer comparisons than a linear search,\n", "but it imposes the requirement that the list be sorted.\n", "\n", "In computer science, a binary search or half-interval search algorithm\n", "finds the position of a specified input value (the search \"key\") within\n", "an array sorted by key value.\n", "\n", "In each step, the algorithm compares the search key value with the key\n", "value of the middle element of the array.\n", "\n", "If the keys match, then a matching element has been found and the range of indices that equal the search key value are returned.\n", "\n", "Otherwise, if the search key is less than the middle element's key, then\n", "the algorithm repeats its action on the sub-array to the left of the\n", "middle element or, if the search key is greater, on the sub-array to the\n", "right.\n", "\n", "If the remaining array to be searched is empty, then the key cannot be\n", "found in the array and a special \"not found\" indication is returned. Search methods in Julia typically return an empty range located at the insertion point in this case.\n", "\n", "A binary search halves the number of items to check with each iteration,\n", "so locating an item (or determining its absence) takes logarithmic time.\n", "A binary search is a dichotomic divide and conquer search algorithm.\n", "\n", "**For simplification, you can assume that all elements of the list to be searched are unique.** Feel free to implement a solution that works on lists with non-unique elements as a bonus task.\n", "\n", "## Bonus task\n", "Implement keyword arguments `by`, `lt` and `rev` so that `by` specifies a transformation applied to all elements of the list, `lt` specifies a comparison and `rev` specifies if the list is ordered in reverse.\n", "\n", "## Source\n", "\n", "Wikipedia [http://en.wikipedia.org/wiki/Binary_search_algorithm](http://en.wikipedia.org/wiki/Binary_search_algorithm)\n", "\n", "Some phrases above and the bonus tasks are taken from the [Julia base documentation (MIT license)](https://docs.julialang.org/en/v1/base/sort/#Base.Sort.searchsorted) of `searchsorted`.\n", "\n", "## Version compatibility\n", "This exercise has been tested on Julia versions >=1.0.\n", "\n", "## Submitting Incomplete Solutions\n", "It's possible to submit an incomplete solution so you can see how others have completed the exercise."] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Your solution"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["# submit"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Test suite"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["using Test\n", "\n", "# include(\"binary-search.jl\")\n", "\n", "@testset \"default binary search\" begin\n", " @testset \"value in array\" begin\n", " @test binarysearch([6], 6) == 1:1\n", " @test binarysearch([1, 3, 4, 6, 8, 9, 11], 6) == 4:4\n", " @test binarysearch([1, 3, 4, 6, 8, 9, 11], 1) == 1:1\n", " @test binarysearch([1, 3, 4, 6, 8, 9, 11], 11) == 7:7\n", " @test binarysearch([1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 634], 144) == 10:10\n", " @test binarysearch([1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377], 21) == 6:6\n", " end\n", " @testset \"value not in array\" begin\n", " @test binarysearch([1, 3, 4, 6, 8, 9, 11], 7) == 5:4\n", " @test binarysearch([1, 3, 4, 6, 8, 9, 11], 0) == 1:0\n", " @test binarysearch([1, 3, 4, 6, 8, 9, 11], 13) == 8:7\n", " @test binarysearch([], 1) == 1:0\n", " @test binarysearch([1, 2], 0) == 1:0\n", " end\n", "end\n", "\n", "@testset \"bonus tasks\" begin\n", " @testset \"reverse search\" begin\n", " @testset \"value in array\" begin\n", " @test_skip binarysearch([6], 6, rev = true) == 1:1\n", " @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 6, rev = true) == 4:4\n", " @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 1, rev = true) == 7:7\n", " @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 11, rev = true) == 1:1\n", " @test_skip binarysearch([634, 377, 233, 144, 89, 55, 34, 21, 13, 8, 5, 3, 1], 144, rev = true) == 4:4\n", " @test_skip binarysearch([377, 233, 144, 89, 55, 34, 21, 13, 8, 5, 3, 1], 21, rev = true) == 7:7\n", " end\n", " @testset \"value not in array\" begin\n", " @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 7, rev = true) == 4:3\n", " @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 0, rev = true) == 8:7\n", " @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 13, rev = true) == 1:0\n", " @test_skip binarysearch([], 1, rev = true) == 1:0\n", " end\n", " end\n", "\n", " @testset \"apply transformation\" begin\n", " @testset \"value in array\" begin\n", " @test_skip binarysearch([5.5], 6, by = round) == 1:1\n", " @test_skip binarysearch([1.1, 2.9, 4.4, 5.5, 8.1, 9.0, 10.8], 6, by = round) == 4:4\n", " @test_skip binarysearch([1.1, 2.9, 4.4, 5.5, 8.1, 9.0, 10.8], 1, by = round) == 1:1\n", " @test_skip binarysearch([1.1, 2.9, 4.4, 5.5, 8.1, 9.0, 10.8], 11, by = round) == 7:7\n", " @test_skip binarysearch([1.1, 2.9, 4.4, 5.5, 8.1, 9.0, 10.8], 11, by = abs2∘round) == 7:7\n", " @test_skip binarysearch([1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 634], 144.4, by = round) == 10:10\n", " @test_skip binarysearch([1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377], 20.6, by = round) == 6:6\n", " end\n", " @testset \"value not in array\" begin\n", " @test_skip binarysearch([1.1, 2.9, 4.4, 5.5, 8.1, 9.0, 10.8], 7, by = round) == 5:4\n", " @test_skip binarysearch([1.1, 2.9, 4.4, 5.5, 8.1, 9.0, 10.8], 0, by = round) == 1:0\n", " @test_skip binarysearch([1.1, 2.9, 4.4, 5.5, 8.1, 9.0, 10.8], 13, by = round) == 8:7\n", " @test_skip binarysearch([], 1, by = round) == 1:0\n", " end\n", " end\n", "\n", " @testset \"compare with > instead of <\" begin\n", " # this is equivalent to searching in reverse order\n", " @testset \"value in array\" begin\n", " @test_skip binarysearch([6], 6, lt = >) == 1:1\n", " @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 6, lt = >) == 4:4\n", " @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 1, lt = >) == 7:7\n", " @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 11, lt = >) == 1:1\n", " @test_skip binarysearch([634, 377, 233, 144, 89, 55, 34, 21, 13, 8, 5, 3, 1], 144, lt = >) == 4:4\n", " @test_skip binarysearch([377, 233, 144, 89, 55, 34, 21, 13, 8, 5, 3, 1], 21, lt = >) == 7:7\n", " end\n", " @testset \"value not in array\" begin\n", " @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 7, lt = >) == 4:3\n", " @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 0, lt = >) == 8:7\n", " @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 13, lt = >) == 1:0\n", " @test_skip binarysearch([], 1, lt = >) == 1:0\n", " end\n", " end\n", "end"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Prepare submission\n", + "To submit your exercise, you need to save your solution in a file called `binary-search.jl` before using the CLI.\n", + "You can either create it manually or use the following functions, which will automatically write every notebook cell that starts with `# submit` to the file `binary-search.jl`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# using Pkg; Pkg.add(\"Exercism\")\n", + "# using Exercism\n", + "# Exercism.create_submission(\"binary-search\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.3.0", + "language": "julia", + "name": "julia-1.3" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.3.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/julia/binary-search/binary-search.jl b/julia/binary-search/binary-search.jl new file mode 100644 index 0000000..282d4be --- /dev/null +++ b/julia/binary-search/binary-search.jl @@ -0,0 +1,14 @@ +function binarysearch(haystack, needle) + lo, hi = 1, length(haystack) + while lo <= hi + idx = Int(floor((hi + lo ) / 2)) + if needle > haystack[idx] + lo = idx + 1 + elseif needle < haystack[idx] + hi = idx - 1 + else + return idx:idx + end + end + lo:hi +end diff --git a/julia/binary-search/runtests.jl b/julia/binary-search/runtests.jl new file mode 100644 index 0000000..cd81ab1 --- /dev/null +++ b/julia/binary-search/runtests.jl @@ -0,0 +1,76 @@ +using Test + +include("binary-search.jl") + +@testset "default binary search" begin + @testset "value in array" begin + @test binarysearch([6], 6) == 1:1 + @test binarysearch([1, 3, 4, 6, 8, 9, 11], 6) == 4:4 + @test binarysearch([1, 3, 4, 6, 8, 9, 11], 1) == 1:1 + @test binarysearch([1, 3, 4, 6, 8, 9, 11], 11) == 7:7 + @test binarysearch([1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 634], 144) == 10:10 + @test binarysearch([1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377], 21) == 6:6 + end + @testset "value not in array" begin + @test binarysearch([1, 3, 4, 6, 8, 9, 11], 7) == 5:4 + @test binarysearch([1, 3, 4, 6, 8, 9, 11], 0) == 1:0 + @test binarysearch([1, 3, 4, 6, 8, 9, 11], 13) == 8:7 + @test binarysearch([], 1) == 1:0 + @test binarysearch([1, 2], 0) == 1:0 + end +end + +@testset "bonus tasks" begin + @testset "reverse search" begin + @testset "value in array" begin + @test_skip binarysearch([6], 6, rev = true) == 1:1 + @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 6, rev = true) == 4:4 + @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 1, rev = true) == 7:7 + @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 11, rev = true) == 1:1 + @test_skip binarysearch([634, 377, 233, 144, 89, 55, 34, 21, 13, 8, 5, 3, 1], 144, rev = true) == 4:4 + @test_skip binarysearch([377, 233, 144, 89, 55, 34, 21, 13, 8, 5, 3, 1], 21, rev = true) == 7:7 + end + @testset "value not in array" begin + @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 7, rev = true) == 4:3 + @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 0, rev = true) == 8:7 + @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 13, rev = true) == 1:0 + @test_skip binarysearch([], 1, rev = true) == 1:0 + end + end + + @testset "apply transformation" begin + @testset "value in array" begin + @test_skip binarysearch([5.5], 6, by = round) == 1:1 + @test_skip binarysearch([1.1, 2.9, 4.4, 5.5, 8.1, 9.0, 10.8], 6, by = round) == 4:4 + @test_skip binarysearch([1.1, 2.9, 4.4, 5.5, 8.1, 9.0, 10.8], 1, by = round) == 1:1 + @test_skip binarysearch([1.1, 2.9, 4.4, 5.5, 8.1, 9.0, 10.8], 11, by = round) == 7:7 + @test_skip binarysearch([1.1, 2.9, 4.4, 5.5, 8.1, 9.0, 10.8], 11, by = abs2∘round) == 7:7 + @test_skip binarysearch([1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 634], 144.4, by = round) == 10:10 + @test_skip binarysearch([1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377], 20.6, by = round) == 6:6 + end + @testset "value not in array" begin + @test_skip binarysearch([1.1, 2.9, 4.4, 5.5, 8.1, 9.0, 10.8], 7, by = round) == 5:4 + @test_skip binarysearch([1.1, 2.9, 4.4, 5.5, 8.1, 9.0, 10.8], 0, by = round) == 1:0 + @test_skip binarysearch([1.1, 2.9, 4.4, 5.5, 8.1, 9.0, 10.8], 13, by = round) == 8:7 + @test_skip binarysearch([], 1, by = round) == 1:0 + end + end + + @testset "compare with > instead of <" begin + # this is equivalent to searching in reverse order + @testset "value in array" begin + @test_skip binarysearch([6], 6, lt = >) == 1:1 + @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 6, lt = >) == 4:4 + @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 1, lt = >) == 7:7 + @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 11, lt = >) == 1:1 + @test_skip binarysearch([634, 377, 233, 144, 89, 55, 34, 21, 13, 8, 5, 3, 1], 144, lt = >) == 4:4 + @test_skip binarysearch([377, 233, 144, 89, 55, 34, 21, 13, 8, 5, 3, 1], 21, lt = >) == 7:7 + end + @testset "value not in array" begin + @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 7, lt = >) == 4:3 + @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 0, lt = >) == 8:7 + @test_skip binarysearch([11, 9, 8, 6, 4, 3, 1], 13, lt = >) == 1:0 + @test_skip binarysearch([], 1, lt = >) == 1:0 + end + end +end diff --git a/julia/minesweeper/.exercism/metadata.json b/julia/minesweeper/.exercism/metadata.json new file mode 100644 index 0000000..bb508b6 --- /dev/null +++ b/julia/minesweeper/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"julia","exercise":"minesweeper","id":"a839588890684ea89e338552c20ab03a","url":"https://exercism.io/my/solutions/a839588890684ea89e338552c20ab03a","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/julia/minesweeper/README.md b/julia/minesweeper/README.md new file mode 100644 index 0000000..7542ca4 --- /dev/null +++ b/julia/minesweeper/README.md @@ -0,0 +1,43 @@ +# Minesweeper + +Add the mine counts to a completed Minesweeper board. + +Minesweeper is a popular game where the user has to find the mines using +numeric hints that indicate how many mines are directly adjacent +(horizontally, vertically, diagonally) to a square. + +In this exercise you have to create some code that counts the number of +mines adjacent to a given empty square and replaces that square with the +count. + +The board is a rectangle composed of blank space (' ') characters. A mine +is represented by an asterisk ('\*') character. + +If a given space has no adjacent mines at all, leave that square blank. + +## Examples + +For example you may receive a 5 x 4 board like this (empty spaces are +represented here with the '·' character for display on screen): + +``` +·*·*· +··*·· +··*·· +····· +``` + +And your code will transform it into this: + +``` +1*3*1 +13*31 +·2*2· +·111· +``` + +## Version compatibility +This exercise has been tested on Julia versions >=1.0. + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/julia/minesweeper/minesweeper.ipynb b/julia/minesweeper/minesweeper.ipynb new file mode 100644 index 0000000..8a575cf --- /dev/null +++ b/julia/minesweeper/minesweeper.ipynb @@ -0,0 +1,68 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": ["# Minesweeper\n", "\n", "Add the mine counts to a completed Minesweeper board.\n", "\n", "Minesweeper is a popular game where the user has to find the mines using\n", "numeric hints that indicate how many mines are directly adjacent\n", "(horizontally, vertically, diagonally) to a square.\n", "\n", "In this exercise you have to create some code that counts the number of\n", "mines adjacent to a given empty square and replaces that square with the\n", "count.\n", "\n", "The board is a rectangle composed of blank space (' ') characters. A mine\n", "is represented by an asterisk ('\\*') character.\n", "\n", "If a given space has no adjacent mines at all, leave that square blank.\n", "\n", "## Examples\n", "\n", "For example you may receive a 5 x 4 board like this (empty spaces are\n", "represented here with the '·' character for display on screen):\n", "\n", "```\n", "·*·*·\n", "··*··\n", "··*··\n", "·····\n", "```\n", "\n", "And your code will transform it into this:\n", "\n", "```\n", "1*3*1\n", "13*31\n", "·2*2·\n", "·111·\n", "```\n", "\n", "## Version compatibility\n", "This exercise has been tested on Julia versions >=1.0.\n", "\n", "## Submitting Incomplete Solutions\n", "It's possible to submit an incomplete solution so you can see how others have completed the exercise."] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Your solution"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["# submit"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Test suite"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["using Test\n", "\n", "# include(\"minesweeper.jl\")\n", "\n", "@testset \"no rows\" begin\n", " @test annotate([]) == []\n", "end\n", "\n", "@testset \"no columns\" begin\n", " @test annotate([\"\"]) == [\"\"]\n", "end\n", "\n", "@testset \"no mines\" begin\n", " minefield = [\" \",\n", " \" \",\n", " \" \"]\n", " out = [\" \",\n", " \" \",\n", " \" \"]\n", " @test annotate(minefield) == out\n", "end\n", "\n", "@testset \"minefield only mines\" begin\n", " minefield = [\"***\",\n", " \"***\",\n", " \"***\"]\n", " out = [\"***\",\n", " \"***\",\n", " \"***\"]\n", " @test annotate(minefield) == out\n", "end\n", "\n", "@testset \"mine surrounded by spaces\" begin\n", " minefield = [\" \",\n", " \" * \",\n", " \" \"]\n", " out = [\"111\",\n", " \"1*1\",\n", " \"111\"]\n", " @test annotate(minefield) == out\n", "end\n", "\n", "@testset \"space surrounded by mines\" begin\n", " minefield = [\"***\",\n", " \"* *\",\n", " \"***\"]\n", " out = [\"***\",\n", " \"*8*\",\n", " \"***\"]\n", " @test annotate(minefield) == out\n", "end\n", "\n", "@testset \"horizontal line\" begin\n", " minefield = [\" * * \"]\n", " out = [\"1*2*1\"]\n", " @test annotate(minefield) == out\n", "end\n", "\n", "@testset \"horizontal line mines at edges\" begin\n", " minefield = [\"* *\"]\n", " out = [\"*1 1*\"]\n", " @test annotate(minefield) == out\n", "end\n", "\n", "@testset \"vertical line\" begin\n", " minefield = [\" \",\n", " \"*\",\n", " \" \",\n", " \"*\",\n", " \" \"]\n", " out = [\"1\",\n", " \"*\",\n", " \"2\",\n", " \"*\",\n", " \"1\"]\n", " @test annotate(minefield) == out\n", "end\n", "\n", "@testset \"vertical line mines at edges\" begin\n", " minefield = [\"*\",\n", " \" \",\n", " \" \",\n", " \" \",\n", " \"*\"]\n", " out = [\"*\",\n", " \"1\",\n", " \" \",\n", " \"1\",\n", " \"*\"]\n", " @test annotate(minefield) == out\n", "end\n", "\n", "@testset \"cross\" begin\n", " minefield = [\" * \",\n", " \" * \",\n", " \"*****\",\n", " \" * \",\n", " \" * \"]\n", " out = [\" 2*2 \",\n", " \"25*52\",\n", " \"*****\",\n", " \"25*52\",\n", " \" 2*2 \"]\n", " @test annotate(minefield) == out\n", "end\n", "\n", "@testset \"large minefield\" begin\n", " minefield = [\" * * \",\n", " \" * \",\n", " \" * \",\n", " \" * *\",\n", " \" * * \",\n", " \" \"]\n", " out = [\"1*22*1\",\n", " \"12*322\",\n", " \" 123*2\",\n", " \"112*4*\",\n", " \"1*22*2\",\n", " \"111111\"]\n", " @test annotate(minefield) == out\n", "end"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Prepare submission\n", + "To submit your exercise, you need to save your solution in a file called `minesweeper.jl` before using the CLI.\n", + "You can either create it manually or use the following functions, which will automatically write every notebook cell that starts with `# submit` to the file `minesweeper.jl`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# using Pkg; Pkg.add(\"Exercism\")\n", + "# using Exercism\n", + "# Exercism.create_submission(\"minesweeper\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.3.0", + "language": "julia", + "name": "julia-1.3" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.3.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/julia/minesweeper/minesweeper.jl b/julia/minesweeper/minesweeper.jl new file mode 100644 index 0000000..52d0561 --- /dev/null +++ b/julia/minesweeper/minesweeper.jl @@ -0,0 +1,25 @@ +function annotate(field) + afield = [] + for x ∈ 1:length(field) + line = "" + for y ∈ 1:length(field[x]) + el = field[x][y] + if el == '*' + line = "$line$el" + continue + end + stars = 0 + if x > 1 + stars += count(c -> c == '*', field[x - 1][max(y - 1, 1):min(y + 1, length(field[x]))]) + end + stars += count(c -> c == '*', field[x][max(y - 1, 1):min(y + 1, length(field[x]))]) + if x < length(field) + stars += count(c -> c == '*', field[x + 1][max(y - 1, 1):min(y + 1, length(field[x]))]) + end + ch = stars == 0 ? " " : "$stars" + line = "$line$ch" + end + append!(afield, [line]) + end + afield +end diff --git a/julia/minesweeper/runtests.jl b/julia/minesweeper/runtests.jl new file mode 100644 index 0000000..70e959d --- /dev/null +++ b/julia/minesweeper/runtests.jl @@ -0,0 +1,121 @@ +using Test + +include("minesweeper.jl") + +@testset "no rows" begin + @test annotate([]) == [] +end + +# @testset "no columns" begin +# @test annotate([""]) == [""] +# end + +@testset "no mines" begin + minefield = [" ", + " ", + " "] + out = [" ", + " ", + " "] + @test annotate(minefield) == out +end + +@testset "minefield only mines" begin + minefield = ["***", + "***", + "***"] + out = ["***", + "***", + "***"] + @test annotate(minefield) == out +end + +@testset "mine surrounded by spaces" begin + minefield = [" ", + " * ", + " "] + out = ["111", + "1*1", + "111"] + @test annotate(minefield) == out +end + +@testset "space surrounded by mines" begin + minefield = ["***", + "* *", + "***"] + out = ["***", + "*8*", + "***"] + @test annotate(minefield) == out +end + +@testset "horizontal line" begin + minefield = [" * * "] + out = ["1*2*1"] + @test annotate(minefield) == out +end + +@testset "horizontal line mines at edges" begin + minefield = ["* *"] + out = ["*1 1*"] + @test annotate(minefield) == out +end + +@testset "vertical line" begin + minefield = [" ", + "*", + " ", + "*", + " "] + out = ["1", + "*", + "2", + "*", + "1"] + @test annotate(minefield) == out +end + +@testset "vertical line mines at edges" begin + minefield = ["*", + " ", + " ", + " ", + "*"] + out = ["*", + "1", + " ", + "1", + "*"] + @test annotate(minefield) == out +end + +@testset "cross" begin + minefield = [" * ", + " * ", + "*****", + " * ", + " * "] + out = [" 2*2 ", + "25*52", + "*****", + "25*52", + " 2*2 "] + @test annotate(minefield) == out +end + +@testset "large minefield" begin + minefield = [" * * ", + " * ", + " * ", + " * *", + " * * ", + " "] + out = ["1*22*1", + "12*322", + " 123*2", + "112*4*", + "1*22*2", + "111111"] + @test annotate(minefield) == out +end diff --git a/julia/pascals-triangle/.exercism/metadata.json b/julia/pascals-triangle/.exercism/metadata.json new file mode 100644 index 0000000..ac786e2 --- /dev/null +++ b/julia/pascals-triangle/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"julia","exercise":"pascals-triangle","id":"802dc59e8eb8489f9fa601b08be5a1ac","url":"https://exercism.io/my/solutions/802dc59e8eb8489f9fa601b08be5a1ac","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/julia/pascals-triangle/README.md b/julia/pascals-triangle/README.md new file mode 100644 index 0000000..ae5f43f --- /dev/null +++ b/julia/pascals-triangle/README.md @@ -0,0 +1,25 @@ +# Pascal's Triangle + +Compute Pascal's triangle up to a given number of rows. + +In Pascal's Triangle each number is computed by adding the numbers to +the right and left of the current position in the previous row. + +```text + 1 + 1 1 + 1 2 1 + 1 3 3 1 +1 4 6 4 1 +# ... etc +``` + +## Source + +Pascal's Triangle at Wolfram Math World [http://mathworld.wolfram.com/PascalsTriangle.html](http://mathworld.wolfram.com/PascalsTriangle.html) + +## Version compatibility +This exercise has been tested on Julia versions >=1.0. + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/julia/pascals-triangle/pascals-triangle.ipynb b/julia/pascals-triangle/pascals-triangle.ipynb new file mode 100644 index 0000000..e311703 --- /dev/null +++ b/julia/pascals-triangle/pascals-triangle.ipynb @@ -0,0 +1,68 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": ["# Pascal's Triangle\n", "\n", "Compute Pascal's triangle up to a given number of rows.\n", "\n", "In Pascal's Triangle each number is computed by adding the numbers to\n", "the right and left of the current position in the previous row.\n", "\n", "```text\n", " 1\n", " 1 1\n", " 1 2 1\n", " 1 3 3 1\n", "1 4 6 4 1\n", "# ... etc\n", "```\n", "\n", "## Source\n", "\n", "Pascal's Triangle at Wolfram Math World [http://mathworld.wolfram.com/PascalsTriangle.html](http://mathworld.wolfram.com/PascalsTriangle.html)\n", "\n", "## Version compatibility\n", "This exercise has been tested on Julia versions >=1.0.\n", "\n", "## Submitting Incomplete Solutions\n", "It's possible to submit an incomplete solution so you can see how others have completed the exercise."] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Your solution"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["# submit\n", "function triangle(n)\n", "\n", "end"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Test suite"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["using Test\n", "\n", "# include(\"pascals-triangle.jl\")\n", "\n", "const rows = [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], [1, 5, 10, 10, 5, 1], [1, 6, 15, 20, 15, 6, 1], [1, 7, 21, 35, 35, 21, 7, 1], [1, 8, 28, 56, 70, 56, 28, 8, 1], [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]]\n", "\n", "@testset \"$i row(s)\" for i in eachindex(rows)\n", " @test triangle(i) == @view rows[1:i]\n", "end\n", "\n", "@testset \"special cases\" begin\n", " @test_throws DomainError triangle(-1)\n", " @test isempty(triangle(0))\n", "end"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Prepare submission\n", + "To submit your exercise, you need to save your solution in a file called `pascals-triangle.jl` before using the CLI.\n", + "You can either create it manually or use the following functions, which will automatically write every notebook cell that starts with `# submit` to the file `pascals-triangle.jl`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# using Pkg; Pkg.add(\"Exercism\")\n", + "# using Exercism\n", + "# Exercism.create_submission(\"pascals-triangle\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.3.0", + "language": "julia", + "name": "julia-1.3" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.3.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/julia/pascals-triangle/pascals-triangle.jl b/julia/pascals-triangle/pascals-triangle.jl new file mode 100644 index 0000000..d318472 --- /dev/null +++ b/julia/pascals-triangle/pascals-triangle.jl @@ -0,0 +1,9 @@ +function triangle(n) + n == 0 && return [] + n < 0 && throw(DomainError("Invalid n given")) + rows = [[1]] + for _ ∈ 2:n + push!(rows, [a+b for (a,b) ∈ zip([0;rows[end]], [rows[end]; 0])]) + end + rows +end diff --git a/julia/pascals-triangle/runtests.jl b/julia/pascals-triangle/runtests.jl new file mode 100644 index 0000000..e1bd53c --- /dev/null +++ b/julia/pascals-triangle/runtests.jl @@ -0,0 +1,14 @@ +using Test + +include("pascals-triangle.jl") + +const rows = [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], [1, 5, 10, 10, 5, 1], [1, 6, 15, 20, 15, 6, 1], [1, 7, 21, 35, 35, 21, 7, 1], [1, 8, 28, 56, 70, 56, 28, 8, 1], [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]] + +@testset "$i row(s)" for i in eachindex(rows) + @test triangle(i) == @view rows[1:i] +end + +@testset "special cases" begin + @test_throws DomainError triangle(-1) + @test isempty(triangle(0)) +end diff --git a/julia/perfect-numbers/.exercism/metadata.json b/julia/perfect-numbers/.exercism/metadata.json new file mode 100644 index 0000000..e55787b --- /dev/null +++ b/julia/perfect-numbers/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"julia","exercise":"perfect-numbers","id":"6aa6745ac14f4533b0a7b20f97053979","url":"https://exercism.io/my/solutions/6aa6745ac14f4533b0a7b20f97053979","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/julia/perfect-numbers/README.md b/julia/perfect-numbers/README.md new file mode 100644 index 0000000..edddd39 --- /dev/null +++ b/julia/perfect-numbers/README.md @@ -0,0 +1,28 @@ +# Perfect Numbers + +Determine if a number is perfect, abundant, or deficient based on +Nicomachus' (60 - 120 CE) classification scheme for natural numbers. + +The Greek mathematician [Nicomachus](https://en.wikipedia.org/wiki/Nicomachus) devised a classification scheme for natural numbers, identifying each as belonging uniquely to the categories of **perfect**, **abundant**, or **deficient** based on their [aliquot sum](https://en.wikipedia.org/wiki/Aliquot_sum). The aliquot sum is defined as the sum of the factors of a number not including the number itself. For example, the aliquot sum of 15 is (1 + 3 + 5) = 9 + +- **Perfect**: aliquot sum = number + - 6 is a perfect number because (1 + 2 + 3) = 6 + - 28 is a perfect number because (1 + 2 + 4 + 7 + 14) = 28 +- **Abundant**: aliquot sum > number + - 12 is an abundant number because (1 + 2 + 3 + 4 + 6) = 16 + - 24 is an abundant number because (1 + 2 + 3 + 4 + 6 + 8 + 12) = 36 +- **Deficient**: aliquot sum < number + - 8 is a deficient number because (1 + 2 + 4) = 7 + - Prime numbers are deficient + +Implement a way to determine whether a given number is **perfect**, **abundant** or **deficient**. + +## Source + +Taken from Chapter 2 of Functional Thinking by Neal Ford. [http://shop.oreilly.com/product/0636920029687.do](http://shop.oreilly.com/product/0636920029687.do) + +## Version compatibility +This exercise has been tested on Julia versions >=1.0. + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/julia/perfect-numbers/perfect-numbers.ipynb b/julia/perfect-numbers/perfect-numbers.ipynb new file mode 100644 index 0000000..7339662 --- /dev/null +++ b/julia/perfect-numbers/perfect-numbers.ipynb @@ -0,0 +1,68 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": ["# Perfect Numbers\n", "\n", "Determine if a number is perfect, abundant, or deficient based on\n", "Nicomachus' (60 - 120 CE) classification scheme for natural numbers.\n", "\n", "The Greek mathematician [Nicomachus](https://en.wikipedia.org/wiki/Nicomachus) devised a classification scheme for natural numbers, identifying each as belonging uniquely to the categories of **perfect**, **abundant**, or **deficient** based on their [aliquot sum](https://en.wikipedia.org/wiki/Aliquot_sum). The aliquot sum is defined as the sum of the factors of a number not including the number itself. For example, the aliquot sum of 15 is (1 + 3 + 5) = 9\n", "\n", "- **Perfect**: aliquot sum = number\n", " - 6 is a perfect number because (1 + 2 + 3) = 6\n", " - 28 is a perfect number because (1 + 2 + 4 + 7 + 14) = 28\n", "- **Abundant**: aliquot sum > number\n", " - 12 is an abundant number because (1 + 2 + 3 + 4 + 6) = 16\n", " - 24 is an abundant number because (1 + 2 + 3 + 4 + 6 + 8 + 12) = 36\n", "- **Deficient**: aliquot sum < number\n", " - 8 is a deficient number because (1 + 2 + 4) = 7\n", " - Prime numbers are deficient\n", "\n", "Implement a way to determine whether a given number is **perfect**, **abundant** or **deficient**.\n", "\n", "## Source\n", "\n", "Taken from Chapter 2 of Functional Thinking by Neal Ford. [http://shop.oreilly.com/product/0636920029687.do](http://shop.oreilly.com/product/0636920029687.do)\n", "\n", "## Version compatibility\n", "This exercise has been tested on Julia versions >=1.0.\n", "\n", "## Submitting Incomplete Solutions\n", "It's possible to submit an incomplete solution so you can see how others have completed the exercise."] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Your solution"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["# submit\n", ""] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Test suite"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["using Test\n", "\n", "# include(\"perfect-numbers.jl\")\n", "\n", "@testset \"Perfect numbers\" begin\n", "\n", " @testset \"Smallest perfect number is classified correctly\" begin\n", " @test isperfect(6)\n", " end\n", "\n", " @testset \"Medium perfect number is classified correctly\" begin\n", " @test isperfect(28)\n", " end\n", "\n", " @testset \"Large perfect number is classified correctly\" begin\n", " @test isperfect(33550336)\n", " end\n", "end\n", "\n", "@testset \"Abundant numbers\" begin\n", "\n", " @testset \"Smallest abundant number is classified correctly\" begin\n", " @test isabundant(12)\n", " end\n", "\n", " @testset \"Medium abundant number is classified correctly\" begin\n", " @test isabundant(30)\n", " end\n", "\n", " @testset \"Large abundant number is classified correctly\" begin\n", " @test isabundant(33550335)\n", " end\n", "end\n", "\n", "@testset \"Deficient numbers\" begin\n", "\n", " @testset \"Smallest prime deficient number is classified correctly\" begin\n", " @test isdeficient(2)\n", " end\n", "\n", " @testset \"Smallest non-prime deficient number is classified correctly\" begin\n", " @test isdeficient(4)\n", " end\n", "\n", " @testset \"Medium deficient number is classified correctly\" begin\n", " @test isdeficient(32)\n", " end\n", "\n", " @testset \"Large deficient number is classified correctly\" begin\n", " @test isdeficient(33550337)\n", " end\n", "\n", " @testset \"Edge case (no factors other than itself) is classified correctly\" begin\n", " @test isdeficient(1)\n", " end\n", "end\n", "\n", "@testset \"Invalid inputs\" begin\n", "\n", " @testset \"Zero is rejected (not a natural number)\" begin\n", " @test_throws DomainError isdeficient(0)\n", " @test_throws DomainError isperfect(0)\n", " @test_throws DomainError isabundant(0)\n", " end\n", "\n", " @testset \"Negative integer is rejected (not a natural number)\" begin\n", " @test_throws DomainError isdeficient(-1)\n", " @test_throws DomainError isperfect(-1)\n", " @test_throws DomainError isabundant(-1)\n", " end\n", "end"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Prepare submission\n", + "To submit your exercise, you need to save your solution in a file called `perfect-numbers.jl` before using the CLI.\n", + "You can either create it manually or use the following functions, which will automatically write every notebook cell that starts with `# submit` to the file `perfect-numbers.jl`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# using Pkg; Pkg.add(\"Exercism\")\n", + "# using Exercism\n", + "# Exercism.create_submission(\"perfect-numbers\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.3.0", + "language": "julia", + "name": "julia-1.3" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.3.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/julia/perfect-numbers/perfect-numbers.jl b/julia/perfect-numbers/perfect-numbers.jl new file mode 100644 index 0000000..ea652eb --- /dev/null +++ b/julia/perfect-numbers/perfect-numbers.jl @@ -0,0 +1,8 @@ +function aliquot_sum(n) + n <= 0 && throw(DomainError("Aliquot sum only exists for natural numbers")) + sum([x for x in 1:div(n, 2) if mod(n, x) == 0]) +end + +isperfect(n) = aliquot_sum(n) == n +isabundant(n) = aliquot_sum(n) > n +isdeficient(n) = aliquot_sum(n) < n diff --git a/julia/perfect-numbers/runtests.jl b/julia/perfect-numbers/runtests.jl new file mode 100644 index 0000000..982d35a --- /dev/null +++ b/julia/perfect-numbers/runtests.jl @@ -0,0 +1,71 @@ +using Test + +include("perfect-numbers.jl") + +@testset "Perfect numbers" begin + + @testset "Smallest perfect number is classified correctly" begin + @test isperfect(6) + end + + @testset "Medium perfect number is classified correctly" begin + @test isperfect(28) + end + + @testset "Large perfect number is classified correctly" begin + @test isperfect(33550336) + end +end + +@testset "Abundant numbers" begin + + @testset "Smallest abundant number is classified correctly" begin + @test isabundant(12) + end + + @testset "Medium abundant number is classified correctly" begin + @test isabundant(30) + end + + @testset "Large abundant number is classified correctly" begin + @test isabundant(33550335) + end +end + +@testset "Deficient numbers" begin + + @testset "Smallest prime deficient number is classified correctly" begin + @test isdeficient(2) + end + + @testset "Smallest non-prime deficient number is classified correctly" begin + @test isdeficient(4) + end + + @testset "Medium deficient number is classified correctly" begin + @test isdeficient(32) + end + + @testset "Large deficient number is classified correctly" begin + @test isdeficient(33550337) + end + + @testset "Edge case (no factors other than itself) is classified correctly" begin + @test isdeficient(1) + end +end + +@testset "Invalid inputs" begin + + @testset "Zero is rejected (not a natural number)" begin + @test_throws DomainError isdeficient(0) + @test_throws DomainError isperfect(0) + @test_throws DomainError isabundant(0) + end + + @testset "Negative integer is rejected (not a natural number)" begin + @test_throws DomainError isdeficient(-1) + @test_throws DomainError isperfect(-1) + @test_throws DomainError isabundant(-1) + end +end diff --git a/julia/prime-factors/.exercism/metadata.json b/julia/prime-factors/.exercism/metadata.json new file mode 100644 index 0000000..98da68f --- /dev/null +++ b/julia/prime-factors/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"julia","exercise":"prime-factors","id":"5198169256b2415da05999facf51ba03","url":"https://exercism.io/my/solutions/5198169256b2415da05999facf51ba03","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/julia/prime-factors/README.md b/julia/prime-factors/README.md new file mode 100644 index 0000000..bb2cc62 --- /dev/null +++ b/julia/prime-factors/README.md @@ -0,0 +1,40 @@ +# Prime Factors + +Compute the prime factors of a given natural number. + +A prime number is only evenly divisible by itself and 1. + +Note that 1 is not a prime number. + +## Example + +What are the prime factors of 60? + +- Our first divisor is 2. 2 goes into 60, leaving 30. +- 2 goes into 30, leaving 15. + - 2 doesn't go cleanly into 15. So let's move on to our next divisor, 3. +- 3 goes cleanly into 15, leaving 5. + - 3 does not go cleanly into 5. The next possible factor is 4. + - 4 does not go cleanly into 5. The next possible factor is 5. +- 5 does go cleanly into 5. +- We're left only with 1, so now, we're done. + +Our successful divisors in that computation represent the list of prime +factors of 60: 2, 2, 3, and 5. + +You can check this yourself: + +- 2 * 2 * 3 * 5 +- = 4 * 15 +- = 60 +- Success! + +## Source + +The Prime Factors Kata by Uncle Bob [http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata](http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata) + +## Version compatibility +This exercise has been tested on Julia versions >=1.0. + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/julia/prime-factors/prime-factors.ipynb b/julia/prime-factors/prime-factors.ipynb new file mode 100644 index 0000000..2595b50 --- /dev/null +++ b/julia/prime-factors/prime-factors.ipynb @@ -0,0 +1,68 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": ["# Prime Factors\n", "\n", "Compute the prime factors of a given natural number.\n", "\n", "A prime number is only evenly divisible by itself and 1.\n", "\n", "Note that 1 is not a prime number.\n", "\n", "## Example\n", "\n", "What are the prime factors of 60?\n", "\n", "- Our first divisor is 2. 2 goes into 60, leaving 30.\n", "- 2 goes into 30, leaving 15.\n", " - 2 doesn't go cleanly into 15. So let's move on to our next divisor, 3.\n", "- 3 goes cleanly into 15, leaving 5.\n", " - 3 does not go cleanly into 5. The next possible factor is 4.\n", " - 4 does not go cleanly into 5. The next possible factor is 5.\n", "- 5 does go cleanly into 5.\n", "- We're left only with 1, so now, we're done.\n", "\n", "Our successful divisors in that computation represent the list of prime\n", "factors of 60: 2, 2, 3, and 5.\n", "\n", "You can check this yourself:\n", "\n", "- 2 * 2 * 3 * 5\n", "- = 4 * 15\n", "- = 60\n", "- Success!\n", "\n", "## Source\n", "\n", "The Prime Factors Kata by Uncle Bob [http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata](http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata)\n", "\n", "## Version compatibility\n", "This exercise has been tested on Julia versions >=1.0.\n", "\n", "## Submitting Incomplete Solutions\n", "It's possible to submit an incomplete solution so you can see how others have completed the exercise."] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Your solution"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["# submit\n", ""] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Test suite"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["# include(\"prime-factors.jl\")\n", "using Test\n", "\n", "@testset \"no factors\" begin\n", " @test prime_factors(1) == []\n", "end\n", "\n", "@testset \"prime number\" begin\n", " @test prime_factors(2) == [2]\n", "end\n", "\n", "@testset \"square of a prime\" begin\n", " @test prime_factors(9) == [3, 3]\n", "end\n", "\n", "@testset \"cube of a prime\" begin\n", " @test prime_factors(8) == [2, 2, 2]\n", "end\n", "\n", "@testset \"product of primes and non-primes\" begin\n", " @test prime_factors(12) == [2, 2, 3]\n", "end\n", "\n", "@testset \"product of primes\" begin\n", " @test prime_factors(901255) == [5, 17, 23, 461]\n", "end\n", "\n", "@testset \"factors include a large prime\" begin\n", " @test prime_factors(93819012551) == [11, 9539, 894119]\n", "end"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Prepare submission\n", + "To submit your exercise, you need to save your solution in a file called `prime-factors.jl` before using the CLI.\n", + "You can either create it manually or use the following functions, which will automatically write every notebook cell that starts with `# submit` to the file `prime-factors.jl`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# using Pkg; Pkg.add(\"Exercism\")\n", + "# using Exercism\n", + "# Exercism.create_submission(\"prime-factors\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.3.0", + "language": "julia", + "name": "julia-1.3" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.3.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/julia/prime-factors/prime-factors.jl b/julia/prime-factors/prime-factors.jl new file mode 100644 index 0000000..85bd2a4 --- /dev/null +++ b/julia/prime-factors/prime-factors.jl @@ -0,0 +1,13 @@ +function prime_factors(n::Int) + primes = [] + while n != 1 && n > 1 + for i in 2:n + if n % i == 0 + push!(primes, i) + n = div(n, i) + break + end + end + end + primes +end diff --git a/julia/prime-factors/runtests.jl b/julia/prime-factors/runtests.jl new file mode 100644 index 0000000..23af245 --- /dev/null +++ b/julia/prime-factors/runtests.jl @@ -0,0 +1,30 @@ +include("prime-factors.jl") +using Test + +@testset "no factors" begin + @test prime_factors(1) == [] +end + +@testset "prime number" begin + @test prime_factors(2) == [2] +end + +@testset "square of a prime" begin + @test prime_factors(9) == [3, 3] +end + +@testset "cube of a prime" begin + @test prime_factors(8) == [2, 2, 2] +end + +@testset "product of primes and non-primes" begin + @test prime_factors(12) == [2, 2, 3] +end + +@testset "product of primes" begin + @test prime_factors(901255) == [5, 17, 23, 461] +end + +@testset "factors include a large prime" begin + @test prime_factors(93819012551) == [11, 9539, 894119] +end diff --git a/julia/run-length-encoding/.exercism/metadata.json b/julia/run-length-encoding/.exercism/metadata.json new file mode 100644 index 0000000..20e983f --- /dev/null +++ b/julia/run-length-encoding/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"julia","exercise":"run-length-encoding","id":"bd55331dd6c8411595b7f396026666c9","url":"https://exercism.io/my/solutions/bd55331dd6c8411595b7f396026666c9","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/julia/run-length-encoding/README.md b/julia/run-length-encoding/README.md new file mode 100644 index 0000000..323e61e --- /dev/null +++ b/julia/run-length-encoding/README.md @@ -0,0 +1,34 @@ +# Run Length Encoding + +Implement run-length encoding and decoding. + +Run-length encoding (RLE) is a simple form of data compression, where runs +(consecutive data elements) are replaced by just one data value and count. + +For example we can represent the original 53 characters with only 13. + +```text +"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" -> "12WB12W3B24WB" +``` + +RLE allows the original data to be perfectly reconstructed from +the compressed data, which makes it a lossless data compression. + +```text +"AABCCCDEEEE" -> "2AB3CD4E" -> "AABCCCDEEEE" +``` + +For simplicity, you can assume that the unencoded string will only contain +the letters A through Z (either lower or upper case) and whitespace. This way +data to be encoded will never contain any numbers and numbers inside data to +be decoded always represent the count for the following character. + +## Source + +Wikipedia [https://en.wikipedia.org/wiki/Run-length_encoding](https://en.wikipedia.org/wiki/Run-length_encoding) + +## Version compatibility +This exercise has been tested on Julia versions >=1.0. + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/julia/run-length-encoding/run-length-encoding.ipynb b/julia/run-length-encoding/run-length-encoding.ipynb new file mode 100644 index 0000000..e1b66a8 --- /dev/null +++ b/julia/run-length-encoding/run-length-encoding.ipynb @@ -0,0 +1,68 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": ["# Run Length Encoding\n", "\n", "Implement run-length encoding and decoding.\n", "\n", "Run-length encoding (RLE) is a simple form of data compression, where runs\n", "(consecutive data elements) are replaced by just one data value and count.\n", "\n", "For example we can represent the original 53 characters with only 13.\n", "\n", "```text\n", "\"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB\" -> \"12WB12W3B24WB\"\n", "```\n", "\n", "RLE allows the original data to be perfectly reconstructed from\n", "the compressed data, which makes it a lossless data compression.\n", "\n", "```text\n", "\"AABCCCDEEEE\" -> \"2AB3CD4E\" -> \"AABCCCDEEEE\"\n", "```\n", "\n", "For simplicity, you can assume that the unencoded string will only contain\n", "the letters A through Z (either lower or upper case) and whitespace. This way\n", "data to be encoded will never contain any numbers and numbers inside data to\n", "be decoded always represent the count for the following character.\n", "\n", "## Source\n", "\n", "Wikipedia [https://en.wikipedia.org/wiki/Run-length_encoding](https://en.wikipedia.org/wiki/Run-length_encoding)\n", "\n", "## Version compatibility\n", "This exercise has been tested on Julia versions >=1.0.\n", "\n", "## Submitting Incomplete Solutions\n", "It's possible to submit an incomplete solution so you can see how others have completed the exercise."] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Your solution"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["# submit\n", "function encode(s)\n", "end\n", "\n", "\n", "\n", "function decode(s)\n", "end"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Test suite"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["using Test\n", "\n", "# include(\"run-length-encoding.jl\")\n", "\n", "\n", "# Tests adapted from `problem-specifications//canonical-data.json` @ v1.0.0\n", "# Encode and decode the strings under the given specifications.\n", "\n", "@testset \"encode strings\" begin\n", " @test encode(\"\") == \"\"\n", " @test encode(\"XYZ\") == \"XYZ\"\n", " @test encode(\"AABBBCCCC\") == \"2A3B4C\"\n", " @test encode(\"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB\") == \"12WB12W3B24WB\"\n", " @test encode(\"aabbbcccc\") == \"2a3b4c\"\n", " @test encode(\" hsqq qww \") == \"2 hs2q q2w2 \"\n", "end\n", "\n", "@testset \"decode strings\" begin\n", " @test decode(\"\") == \"\"\n", " @test decode(\"XYZ\") == \"XYZ\"\n", " @test decode(\"2A3B4C\") == \"AABBBCCCC\"\n", " @test decode(\"12WB12W3B24WB\") == \"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB\"\n", " @test decode(\"2a3b4c\") == \"aabbbcccc\"\n", " @test decode(\"2 hs2q q2w2 \") == \" hsqq qww \"\n", "end\n", "\n", "@testset \"encode then decode\" begin\n", " @test decode(encode(\"zzz ZZ zZ\")) == \"zzz ZZ zZ\"\n", "end"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Prepare submission\n", + "To submit your exercise, you need to save your solution in a file called `run-length-encoding.jl` before using the CLI.\n", + "You can either create it manually or use the following functions, which will automatically write every notebook cell that starts with `# submit` to the file `run-length-encoding.jl`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# using Pkg; Pkg.add(\"Exercism\")\n", + "# using Exercism\n", + "# Exercism.create_submission(\"run-length-encoding\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.3.0", + "language": "julia", + "name": "julia-1.3" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.3.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/julia/run-length-encoding/run-length-encoding.jl b/julia/run-length-encoding/run-length-encoding.jl new file mode 100644 index 0000000..07fb5b4 --- /dev/null +++ b/julia/run-length-encoding/run-length-encoding.jl @@ -0,0 +1,34 @@ +function encode(s) + ch = nothing + cnt = 1 + result = "" + for c ∈ s + if ch ≡ nothing + ch = c + continue + end + if ch == c + cnt += 1 + else + result *= cnt > 1 ? "$cnt$ch" : "$ch" + ch = c + cnt = 1 + end + end + if ch ≢ nothing + result *= cnt > 1 ? "$cnt$ch" : "$ch" + end + result +end + + + +function decode(s) + items = collect(eachmatch(r"(\d+)?(.)", s)) + result = "" + for item ∈ items + cnt = parse(Int, (item[1] ≡ nothing) ? "1" : item[1]) + result *= item[2]^cnt + end + result +end diff --git a/julia/run-length-encoding/runtests.jl b/julia/run-length-encoding/runtests.jl new file mode 100644 index 0000000..a406714 --- /dev/null +++ b/julia/run-length-encoding/runtests.jl @@ -0,0 +1,29 @@ +using Test + +include("run-length-encoding.jl") + + +# Tests adapted from `problem-specifications//canonical-data.json` @ v1.0.0 +# Encode and decode the strings under the given specifications. + +@testset "encode strings" begin + @test encode("") == "" + @test encode("XYZ") == "XYZ" + @test encode("AABBBCCCC") == "2A3B4C" + @test encode("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB") == "12WB12W3B24WB" + @test encode("aabbbcccc") == "2a3b4c" + @test encode(" hsqq qww ") == "2 hs2q q2w2 " +end + +@testset "decode strings" begin + @test decode("") == "" + @test decode("XYZ") == "XYZ" + @test decode("2A3B4C") == "AABBBCCCC" + @test decode("12WB12W3B24WB") == "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" + @test decode("2a3b4c") == "aabbbcccc" + @test decode("2 hs2q q2w2 ") == " hsqq qww " +end + +@testset "encode then decode" begin + @test decode(encode("zzz ZZ zZ")) == "zzz ZZ zZ" +end diff --git a/julia/scrabble-score/.exercism/metadata.json b/julia/scrabble-score/.exercism/metadata.json new file mode 100644 index 0000000..276982b --- /dev/null +++ b/julia/scrabble-score/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"julia","exercise":"scrabble-score","id":"eb4d940ab0c344d19a57272dc9fe3da9","url":"https://exercism.io/my/solutions/eb4d940ab0c344d19a57272dc9fe3da9","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/julia/scrabble-score/README.md b/julia/scrabble-score/README.md new file mode 100644 index 0000000..864c31d --- /dev/null +++ b/julia/scrabble-score/README.md @@ -0,0 +1,50 @@ +# Scrabble Score + +Given a word, compute the Scrabble score for that word. + +## Letter Values + +You'll need these: + +```text +Letter Value +A, E, I, O, U, L, N, R, S, T 1 +D, G 2 +B, C, M, P 3 +F, H, V, W, Y 4 +K 5 +J, X 8 +Q, Z 10 +``` + +## Examples + +"cabbage" should be scored as worth 14 points: + +- 3 points for C +- 1 point for A, twice +- 3 points for B, twice +- 2 points for G +- 1 point for E + +And to total: + +- `3 + 2*1 + 2*3 + 2 + 1` +- = `3 + 2 + 6 + 3` +- = `5 + 9` +- = 14 + +## Extensions + +- You can play a double or a triple letter. +- You can play a double or a triple word. + +## Source + +Inspired by the Extreme Startup game [https://github.com/rchatley/extreme_startup](https://github.com/rchatley/extreme_startup) + +## Version compatibility +This exercise has been tested on Julia versions >=1.0. + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/julia/scrabble-score/runtests.jl b/julia/scrabble-score/runtests.jl new file mode 100644 index 0000000..99611a4 --- /dev/null +++ b/julia/scrabble-score/runtests.jl @@ -0,0 +1,51 @@ +using Test + +include("scrabble-score.jl") + +@testset "lowercase letter" begin + @test score("a") == 1 +end + +@testset "uppercase letter" begin + @test score("A") == 1 +end + +@testset "valuable letter" begin + @test score("f") == 4 +end + +@testset "short word" begin + @test score("at") == 2 +end + +@testset "short, valuable word" begin + @test score("zoo") == 12 +end + +@testset "medium word" begin + @test score("street") == 6 +end + +@testset "medium, valuable word" begin + @test score("quirky") == 22 +end + +@testset "long, mixed-case word" begin + @test score("OxyphenButazone") == 41 +end + +@testset "english-like word" begin + @test score("pinata") == 8 +end + +@testset "non-english letter is not scored" begin + @test score("piñata") == 7 +end + +@testset "empty input" begin + @test score("") == 0 +end + +@testset "entire alphabet available" begin + @test score("abcdefghijklmnopqrstuvwxyz") == 87 +end diff --git a/julia/scrabble-score/scrabble-score.ipynb b/julia/scrabble-score/scrabble-score.ipynb new file mode 100644 index 0000000..99ab845 --- /dev/null +++ b/julia/scrabble-score/scrabble-score.ipynb @@ -0,0 +1,68 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": ["# Scrabble Score\n", "\n", "Given a word, compute the Scrabble score for that word.\n", "\n", "## Letter Values\n", "\n", "You'll need these:\n", "\n", "```text\n", "Letter Value\n", "A, E, I, O, U, L, N, R, S, T 1\n", "D, G 2\n", "B, C, M, P 3\n", "F, H, V, W, Y 4\n", "K 5\n", "J, X 8\n", "Q, Z 10\n", "```\n", "\n", "## Examples\n", "\n", "\"cabbage\" should be scored as worth 14 points:\n", "\n", "- 3 points for C\n", "- 1 point for A, twice\n", "- 3 points for B, twice\n", "- 2 points for G\n", "- 1 point for E\n", "\n", "And to total:\n", "\n", "- `3 + 2*1 + 2*3 + 2 + 1`\n", "- = `3 + 2 + 6 + 3`\n", "- = `5 + 9`\n", "- = 14\n", "\n", "## Extensions\n", "\n", "- You can play a double or a triple letter.\n", "- You can play a double or a triple word.\n", "\n", "## Source\n", "\n", "Inspired by the Extreme Startup game [https://github.com/rchatley/extreme_startup](https://github.com/rchatley/extreme_startup)\n", "\n", "## Version compatibility\n", "This exercise has been tested on Julia versions >=1.0.\n", "\n", "## Submitting Incomplete Solutions\n", "It's possible to submit an incomplete solution so you can see how others have completed the exercise."] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Your solution"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["# submit\n", "function score(str)\n", "\n", "end"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Test suite"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["using Test\n", "\n", "# include(\"scrabble-score.jl\")\n", "\n", "@testset \"lowercase letter\" begin\n", " @test score(\"a\") == 1\n", "end\n", "\n", "@testset \"uppercase letter\" begin\n", " @test score(\"A\") == 1\n", "end\n", "\n", "@testset \"valuable letter\" begin\n", " @test score(\"f\") == 4\n", "end\n", "\n", "@testset \"short word\" begin\n", " @test score(\"at\") == 2\n", "end\n", "\n", "@testset \"short, valuable word\" begin\n", " @test score(\"zoo\") == 12\n", "end\n", "\n", "@testset \"medium word\" begin\n", " @test score(\"street\") == 6\n", "end\n", "\n", "@testset \"medium, valuable word\" begin\n", " @test score(\"quirky\") == 22\n", "end\n", "\n", "@testset \"long, mixed-case word\" begin\n", " @test score(\"OxyphenButazone\") == 41\n", "end\n", "\n", "@testset \"english-like word\" begin\n", " @test score(\"pinata\") == 8\n", "end\n", "\n", "@testset \"non-english letter is not scored\" begin\n", " @test score(\"piñata\") == 7\n", "end\n", "\n", "@testset \"empty input\" begin\n", " @test score(\"\") == 0\n", "end\n", "\n", "@testset \"entire alphabet available\" begin\n", " @test score(\"abcdefghijklmnopqrstuvwxyz\") == 87\n", "end"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Prepare submission\n", + "To submit your exercise, you need to save your solution in a file called `scrabble-score.jl` before using the CLI.\n", + "You can either create it manually or use the following functions, which will automatically write every notebook cell that starts with `# submit` to the file `scrabble-score.jl`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# using Pkg; Pkg.add(\"Exercism\")\n", + "# using Exercism\n", + "# Exercism.create_submission(\"scrabble-score\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.3.0", + "language": "julia", + "name": "julia-1.3" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.3.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/julia/scrabble-score/scrabble-score.jl b/julia/scrabble-score/scrabble-score.jl new file mode 100644 index 0000000..c06a7b5 --- /dev/null +++ b/julia/scrabble-score/scrabble-score.jl @@ -0,0 +1,36 @@ +const CHARACTER_SCORES = Dict( + 'A' => 1, + 'E' => 1, + 'I' => 1, + 'O' => 1, + 'U' => 1, + 'L' => 1, + 'N' => 1, + 'R' => 1, + 'S' => 1, + 'T' => 1, + 'D' => 2, + 'G' => 2, + 'B' => 3, + 'C' => 3, + 'M' => 3, + 'P' => 3, + 'F' => 4, + 'H' => 4, + 'V' => 4, + 'W' => 4, + 'Y' => 4, + 'K' => 5, + 'J' => 8, + 'X' => 8, + 'Q' => 10, + 'Z' => 10 +) + +function score(str::AbstractString) + sum([score(uppercase(c)) for c in str]) +end + +function score(c::Char) + get(CHARACTER_SCORES, c, 0) +end diff --git a/julia/triangle/.exercism/metadata.json b/julia/triangle/.exercism/metadata.json new file mode 100644 index 0000000..d74271f --- /dev/null +++ b/julia/triangle/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"julia","exercise":"triangle","id":"0d677e9f53324414bd3d0bcf8c468849","url":"https://exercism.io/my/solutions/0d677e9f53324414bd3d0bcf8c468849","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/julia/triangle/README.md b/julia/triangle/README.md new file mode 100644 index 0000000..9c0ae55 --- /dev/null +++ b/julia/triangle/README.md @@ -0,0 +1,33 @@ +# Triangle + +Determine if a triangle is equilateral, isosceles, or scalene. + +An _equilateral_ triangle has all three sides the same length. + +An _isosceles_ triangle has at least two sides the same length. (It is sometimes +specified as having exactly two sides the same length, but for the purposes of +this exercise we'll say at least two.) + +A _scalene_ triangle has all sides of different lengths. + +## Note + +For a shape to be a triangle at all, all sides have to be of length > 0, and +the sum of the lengths of any two sides must be greater than or equal to the +length of the third side. See [Triangle Inequality](https://en.wikipedia.org/wiki/Triangle_inequality). + +## Dig Deeper + +The case where the sum of the lengths of two sides _equals_ that of the +third is known as a _degenerate_ triangle - it has zero area and looks like +a single line. Feel free to add your own code/tests to check for degenerate triangles. + +## Source + +The Ruby Koans triangle project, parts 1 & 2 [http://rubykoans.com](http://rubykoans.com) + +## Version compatibility +This exercise has been tested on Julia versions >=1.0. + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/julia/triangle/runtests.jl b/julia/triangle/runtests.jl new file mode 100644 index 0000000..7dcaf45 --- /dev/null +++ b/julia/triangle/runtests.jl @@ -0,0 +1,64 @@ +using Test + +include("triangle.jl") + +@testset "check equilateral triangles" begin + @testset "true if all sides are equal" begin + @test is_equilateral([2, 2, 2]) == true + @test is_equilateral([0.5, 0.5, 0.5]) == true + end + + @testset "false if any side is unequal" begin + @test is_equilateral([2, 3, 2]) == false + end + + @testset "false if no sides are equal" begin + @test is_equilateral([5, 4, 6]) == false + end + + @testset "false if invalid triangle" begin + @test is_equilateral([0, 0, 0]) == false + end +end + +@testset "check isosceles triangles" begin + @testset "true if at least 2 sides are equal" begin + @test is_isosceles([3, 4, 4]) == true + @test is_isosceles([4, 3, 4]) == true + @test is_isosceles([4, 4, 3]) == true + @test is_isosceles([4, 4, 4]) == true + @test is_isosceles([0.4, 0.5, 0.5]) == true + @test is_isosceles([0.5, 0.4, 0.5]) == true + @test is_isosceles([0.5, 0.5, 0.4]) == true + end + + @testset "false if no sides are equal" begin + @test is_isosceles([2, 3, 4]) == false + end + + @testset "false if invalid triangle" begin + @test is_isosceles([1, 1, 3]) == false + end +end + + +@testset "check scalene triangles" begin + @testset "true if no sides are equal" begin + @test is_scalene([5, 4, 6]) == true + @test is_scalene([0.5, 0.4, 0.6]) == true + end + + @testset "false if at least 2 sides are equal" begin + @test is_scalene([3, 4, 4]) == false + @test is_scalene([4, 3, 4]) == false + @test is_scalene([4, 4, 3]) == false + @test is_scalene([4, 4, 4]) == false + @test is_scalene([0.4, 0.5, 0.5]) == false + @test is_scalene([0.5, 0.4, 0.5]) == false + @test is_scalene([0.5, 0.5, 0.4]) == false + end + + @testset "false if invalid triangle" begin + @test is_scalene([7, 3, 2]) == false + end +end diff --git a/julia/triangle/triangle.ipynb b/julia/triangle/triangle.ipynb new file mode 100644 index 0000000..5b5a076 --- /dev/null +++ b/julia/triangle/triangle.ipynb @@ -0,0 +1,68 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": ["# Triangle\n", "\n", "Determine if a triangle is equilateral, isosceles, or scalene.\n", "\n", "An _equilateral_ triangle has all three sides the same length.\n", "\n", "An _isosceles_ triangle has at least two sides the same length. (It is sometimes\n", "specified as having exactly two sides the same length, but for the purposes of\n", "this exercise we'll say at least two.)\n", "\n", "A _scalene_ triangle has all sides of different lengths.\n", "\n", "## Note\n", "\n", "For a shape to be a triangle at all, all sides have to be of length > 0, and\n", "the sum of the lengths of any two sides must be greater than or equal to the\n", "length of the third side. See [Triangle Inequality](https://en.wikipedia.org/wiki/Triangle_inequality).\n", "\n", "## Dig Deeper\n", "\n", "The case where the sum of the lengths of two sides _equals_ that of the\n", "third is known as a _degenerate_ triangle - it has zero area and looks like\n", "a single line. Feel free to add your own code/tests to check for degenerate triangles.\n", "\n", "## Source\n", "\n", "The Ruby Koans triangle project, parts 1 & 2 [http://rubykoans.com](http://rubykoans.com)\n", "\n", "## Version compatibility\n", "This exercise has been tested on Julia versions >=1.0.\n", "\n", "## Submitting Incomplete Solutions\n", "It's possible to submit an incomplete solution so you can see how others have completed the exercise."] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Your solution"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["# submit\n", "function is_equilateral(sides)\n", "end\n", "\n", "function is_isosceles(sides)\n", "end\n", "\n", "function is_scalene(sides)\n", "end"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Test suite"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["using Test\n", "\n", "# include(\"triangle.jl\")\n", "\n", "@testset \"check equilateral triangles\" begin\n", " @testset \"true if all sides are equal\" begin\n", " @test is_equilateral([2, 2, 2]) == true\n", " @test is_equilateral([0.5, 0.5, 0.5]) == true\n", " end\n", "\n", " @testset \"false if any side is unequal\" begin\n", " @test is_equilateral([2, 3, 2]) == false\n", " end\n", "\n", " @testset \"false if no sides are equal\" begin\n", " @test is_equilateral([5, 4, 6]) == false\n", " end\n", "\n", " @testset \"false if invalid triangle\" begin\n", " @test is_equilateral([0, 0, 0]) == false\n", " end\n", "end\n", "\n", "@testset \"check isosceles triangles\" begin\n", " @testset \"true if at least 2 sides are equal\" begin\n", " @test is_isosceles([3, 4, 4]) == true\n", " @test is_isosceles([4, 3, 4]) == true\n", " @test is_isosceles([4, 4, 3]) == true\n", " @test is_isosceles([4, 4, 4]) == true\n", " @test is_isosceles([0.4, 0.5, 0.5]) == true\n", " @test is_isosceles([0.5, 0.4, 0.5]) == true\n", " @test is_isosceles([0.5, 0.5, 0.4]) == true\n", " end\n", "\n", " @testset \"false if no sides are equal\" begin\n", " @test is_isosceles([2, 3, 4]) == false\n", " end\n", "\n", " @testset \"false if invalid triangle\" begin\n", " @test is_isosceles([1, 1, 3]) == false\n", " end\n", "end\n", "\n", "\n", "@testset \"check scalene triangles\" begin\n", " @testset \"true if no sides are equal\" begin\n", " @test is_scalene([5, 4, 6]) == true\n", " @test is_scalene([0.5, 0.4, 0.6]) == true\n", " end\n", "\n", " @testset \"false if at least 2 sides are equal\" begin\n", " @test is_scalene([3, 4, 4]) == false\n", " @test is_scalene([4, 3, 4]) == false\n", " @test is_scalene([4, 4, 3]) == false\n", " @test is_scalene([4, 4, 4]) == false\n", " @test is_scalene([0.4, 0.5, 0.5]) == false\n", " @test is_scalene([0.5, 0.4, 0.5]) == false\n", " @test is_scalene([0.5, 0.5, 0.4]) == false\n", " end\n", "\n", " @testset \"false if invalid triangle\" begin\n", " @test is_scalene([7, 3, 2]) == false\n", " end\n", "end"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Prepare submission\n", + "To submit your exercise, you need to save your solution in a file called `triangle.jl` before using the CLI.\n", + "You can either create it manually or use the following functions, which will automatically write every notebook cell that starts with `# submit` to the file `triangle.jl`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# using Pkg; Pkg.add(\"Exercism\")\n", + "# using Exercism\n", + "# Exercism.create_submission(\"triangle\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.3.0", + "language": "julia", + "name": "julia-1.3" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.3.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/julia/triangle/triangle.jl b/julia/triangle/triangle.jl new file mode 100644 index 0000000..1a2bee0 --- /dev/null +++ b/julia/triangle/triangle.jl @@ -0,0 +1,14 @@ +is_equilateral(sides) = is_valid(sides) && (sides[1] == sides[2] == sides[3]) + +function is_isosceles(sides) + is_valid(sides) && (sides[1] == sides[2] || sides[1] == sides[3] || sides[2] == sides[3]) +end + +function is_scalene(sides) + is_valid(sides) && !is_isosceles(sides) +end + +function is_valid(sides) + sides = sort(sides) + (sides[1] + sides[2] > sides[3]) && all(i -> i > 0, sides) +end diff --git a/julia/trinary/.exercism/metadata.json b/julia/trinary/.exercism/metadata.json new file mode 100644 index 0000000..b621a3a --- /dev/null +++ b/julia/trinary/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"julia","exercise":"trinary","id":"a33190c993fa4f9c917b0c33141e98a3","url":"https://exercism.io/my/solutions/a33190c993fa4f9c917b0c33141e98a3","handle":"halfdan","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/julia/trinary/README.md b/julia/trinary/README.md new file mode 100644 index 0000000..701e809 --- /dev/null +++ b/julia/trinary/README.md @@ -0,0 +1,32 @@ +# Trinary + +Convert a trinary number, represented as a string (e.g. '102012'), to its +decimal equivalent using first principles. + +The program should consider strings specifying an invalid trinary as the +value 0. + +Trinary numbers contain three symbols: 0, 1, and 2. + +The last place in a trinary number is the 1's place. The second to last +is the 3's place, the third to last is the 9's place, etc. + +```shell +# "102012" + 1 0 2 0 1 2 # the number +1*3^5 + 0*3^4 + 2*3^3 + 0*3^2 + 1*3^1 + 2*3^0 # the value + 243 + 0 + 54 + 0 + 3 + 2 = 302 +``` + +If your language provides a method in the standard library to perform the +conversion, pretend it doesn't exist and implement it yourself. + +## Source + +All of Computer Science [http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-](http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-) + +## Version compatibility +This exercise has been tested on Julia versions >=1.0. + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/julia/trinary/runtests.jl b/julia/trinary/runtests.jl new file mode 100644 index 0000000..93f7bdc --- /dev/null +++ b/julia/trinary/runtests.jl @@ -0,0 +1,47 @@ +using Test + +include("trinary.jl") + +@testset "trinary 1 is decimal 1" begin + @test trinary_to_decimal("1") == 1 +end + +@testset "trinary 2 is decimal 2" begin + @test trinary_to_decimal("2") == 2 +end + +@testset "trinary 10 is decimal 3" begin + @test trinary_to_decimal("10") == 3 +end + +@testset "trinary 11 is decimal 4" begin + @test trinary_to_decimal("11") == 4 +end + +@testset "trinary 100 is decimal 9" begin + @test trinary_to_decimal("100") == 9 +end + +@testset "trinary 112 is decimal 14" begin + @test trinary_to_decimal("112") == 14 +end + +@testset "trinary 222 is decimal 26" begin + @test trinary_to_decimal("222") == 26 +end + +@testset "trinary 1122000120 is decimal 32091" begin + @test trinary_to_decimal("1122000120") == 32091 +end + +@testset "invalid trinary digits returns 0" begin + @test trinary_to_decimal("1234") == 0 +end + +@testset "invalid word as input returns 0" begin + @test trinary_to_decimal("carrot") == 0 +end + +@testset "invalid numbers with letters as input returns 0" begin + @test trinary_to_decimal("0a1b2c") == 0 +end diff --git a/julia/trinary/trinary.ipynb b/julia/trinary/trinary.ipynb new file mode 100644 index 0000000..baac729 --- /dev/null +++ b/julia/trinary/trinary.ipynb @@ -0,0 +1,68 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": ["# Trinary\n", "\n", "Convert a trinary number, represented as a string (e.g. '102012'), to its\n", "decimal equivalent using first principles.\n", "\n", "The program should consider strings specifying an invalid trinary as the\n", "value 0.\n", "\n", "Trinary numbers contain three symbols: 0, 1, and 2.\n", "\n", "The last place in a trinary number is the 1's place. The second to last\n", "is the 3's place, the third to last is the 9's place, etc.\n", "\n", "```shell\n", "# \"102012\"\n", " 1 0 2 0 1 2 # the number\n", "1*3^5 + 0*3^4 + 2*3^3 + 0*3^2 + 1*3^1 + 2*3^0 # the value\n", " 243 + 0 + 54 + 0 + 3 + 2 = 302\n", "```\n", "\n", "If your language provides a method in the standard library to perform the\n", "conversion, pretend it doesn't exist and implement it yourself.\n", "\n", "## Source\n", "\n", "All of Computer Science [http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-](http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-)\n", "\n", "## Version compatibility\n", "This exercise has been tested on Julia versions >=1.0.\n", "\n", "## Submitting Incomplete Solutions\n", "It's possible to submit an incomplete solution so you can see how others have completed the exercise."] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Your solution"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["# submit\n", "function trinary_to_decimal(str)\n", "\n", "end"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": ["## Test suite"] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": ["using Test\n", "\n", "# include(\"trinary.jl\")\n", "\n", "@testset \"trinary 1 is decimal 1\" begin\n", " @test trinary_to_decimal(\"1\") == 1\n", "end\n", "\n", "@testset \"trinary 2 is decimal 2\" begin\n", " @test trinary_to_decimal(\"2\") == 2\n", "end\n", "\n", "@testset \"trinary 10 is decimal 3\" begin\n", " @test trinary_to_decimal(\"10\") == 3\n", "end\n", "\n", "@testset \"trinary 11 is decimal 4\" begin\n", " @test trinary_to_decimal(\"11\") == 4\n", "end\n", "\n", "@testset \"trinary 100 is decimal 9\" begin\n", " @test trinary_to_decimal(\"100\") == 9\n", "end\n", "\n", "@testset \"trinary 112 is decimal 14\" begin\n", " @test trinary_to_decimal(\"112\") == 14\n", "end\n", "\n", "@testset \"trinary 222 is decimal 26\" begin\n", " @test trinary_to_decimal(\"222\") == 26\n", "end\n", "\n", "@testset \"trinary 1122000120 is decimal 32091\" begin\n", " @test trinary_to_decimal(\"1122000120\") == 32091\n", "end\n", "\n", "@testset \"invalid trinary digits returns 0\" begin\n", " @test trinary_to_decimal(\"1234\") == 0\n", "end\n", "\n", "@testset \"invalid word as input returns 0\" begin\n", " @test trinary_to_decimal(\"carrot\") == 0\n", "end\n", "\n", "@testset \"invalid numbers with letters as input returns 0\" begin\n", " @test trinary_to_decimal(\"0a1b2c\") == 0\n", "end"] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Prepare submission\n", + "To submit your exercise, you need to save your solution in a file called `trinary.jl` before using the CLI.\n", + "You can either create it manually or use the following functions, which will automatically write every notebook cell that starts with `# submit` to the file `trinary.jl`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# using Pkg; Pkg.add(\"Exercism\")\n", + "# using Exercism\n", + "# Exercism.create_submission(\"trinary\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.3.0", + "language": "julia", + "name": "julia-1.3" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.3.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/julia/trinary/trinary.jl b/julia/trinary/trinary.jl new file mode 100644 index 0000000..1f4e518 --- /dev/null +++ b/julia/trinary/trinary.jl @@ -0,0 +1,6 @@ +function trinary_to_decimal(str) + all(x -> x ∈ ('0', '1', '2'), str) || return 0 + number = parse(Int, str) + digs = digits(number) + sum([k*3^(i-1) for (i,k) in enumerate(digs)]) +end