From 2b98129847adfd31fa03d6ed01d9fb36eef5eb0d Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Fri, 31 Jan 2020 19:28:45 +0100 Subject: [PATCH 001/102] Extract concepts of v2 nucleotide-count exercise --- .../exercise-concepts/nucleotide-count.md | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 reference/exercise-concepts/nucleotide-count.md diff --git a/reference/exercise-concepts/nucleotide-count.md b/reference/exercise-concepts/nucleotide-count.md new file mode 100644 index 0000000000..ce28e936a6 --- /dev/null +++ b/reference/exercise-concepts/nucleotide-count.md @@ -0,0 +1,48 @@ +# Concepts of nucleotide-count + +## General + +- class level methods: used as the starting point of the exercise. They may be named with `self.method_name` notation or with a `self` block. Another way of creating class methods is extending a module. +- module methods: depending on the approach, they may be used instead of the class methods. +- factory pattern and object creation: the method `from_dna` may be used to create instances of the main class. +- instance variables: store the common value/state for the instance. +- accessors: `att_reader` may be used to access instance variables. +- access modifiers: `private` may be used to restrict access to the readers. +- method definition: the `histogram` method needs to be defined. +- method arguments: the method `from_dna` needs an argument. +- strings: one string is passed as the input so it may be necessary to know about strings and string manipulation. +- mixins: one way of solving this exercise is including the `Enumerable` module so it may be necessary to know about Ruby mixins like `Enumerable` or `Comparable`. +- loops: it may be necessary to iterate over the input data using loops and indexes. +- collections: may be used to iterate or transform the input data. Some collections' methods that may be used: `inject, each, each_with_object, count` +- exceptions: necessary to raise an exception if the input is not valid. +- return values: methods need to return values either implicitly or explicitly. +- constants: constants may be used to store static information like DNA values. +- namespaces: namespaces may be used along with constants. +- conditional statements: conditional statements may be used to check if the input is valid. +- blocks: they are used in any of the `Enumerable` methods. +- regular expressions: may be used to validate the input. + +## Approach: use `Enumerable` mixin + +- Make the class that represents the nucleotides strand to include `Enumerable` so that all `Enumerable` methods are available. +- Requires implementation of `each` method. See [Enumerable mixin documentation](https://ruby-doc.org/core-2.7.0/Enumerable.html) + +## Approach: Use collections + `Enumerable` methods. + +- Use `Enumerable#count` to count nucleotide occurrences. +- Use `String#chars` and `Enumerable#each_with_object` to create the histogram + +## Approach: Use indexes to loop over the chars. + +- Similar to the previous approach but using indexes and loops to iterate over an `Array` of characters. + +## Approach: Use collections + String#count and Regex. + +- Use `String#count` to count nucleotide occurrences. +- Initialize a hash for the histogram then use `Enumerable#each` and `String#count` to fill it. +- Use Regex to validate the input. + +## Approach: Use collections + String#count. +- Similar to the previous approach but using `String#count` and `String#size` to validate the input. +- For the input validation part it's also possible to use array difference to remove nucleotides from the input resulting in an empty collection for the valid inputs. + From 09f71278365a6a61bbdc3934a203db5e59ad430a Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Thu, 20 Feb 2020 21:08:10 +0100 Subject: [PATCH 002/102] Strings concept exercise * Strings concept exercise * Add strings concept exercise to the config.json * Add String manipulation phrase in the introduction * Rename class LogLine to module LogLineParser * Update languages/exercises/concept/strings/.docs/instructions.md Co-Authored-By: Jeremy Walker * Add Ruby implementation to the referece * Update languages/exercises/concept/strings/.docs/hints.md Co-Authored-By: Jeremy Walker * Update languages/exercises/concept/strings/.docs/hints.md Co-Authored-By: Jeremy Walker * Improve after text Co-authored-by: Jeremy Walker --- exercises/concept/strings/.docs/after.md | 13 +++++ exercises/concept/strings/.docs/hints.md | 25 ++++++++++ .../concept/strings/.docs/instructions.md | 47 +++++++++++++++++ .../concept/strings/.docs/introduction.md | 4 ++ exercises/concept/strings/.meta/config.json | 8 +++ exercises/concept/strings/.meta/design.md | 41 +++++++++++++++ exercises/concept/strings/.meta/example.rb | 15 ++++++ exercises/concept/strings/log_line_parser.rb | 15 ++++++ .../concept/strings/log_line_parser_test.rb | 50 +++++++++++++++++++ 9 files changed, 218 insertions(+) create mode 100644 exercises/concept/strings/.docs/after.md create mode 100644 exercises/concept/strings/.docs/hints.md create mode 100644 exercises/concept/strings/.docs/instructions.md create mode 100644 exercises/concept/strings/.docs/introduction.md create mode 100644 exercises/concept/strings/.meta/config.json create mode 100644 exercises/concept/strings/.meta/design.md create mode 100644 exercises/concept/strings/.meta/example.rb create mode 100644 exercises/concept/strings/log_line_parser.rb create mode 100644 exercises/concept/strings/log_line_parser_test.rb diff --git a/exercises/concept/strings/.docs/after.md b/exercises/concept/strings/.docs/after.md new file mode 100644 index 0000000000..921c22243c --- /dev/null +++ b/exercises/concept/strings/.docs/after.md @@ -0,0 +1,13 @@ +# After + +The key thing to remember about Ruby strings is that they are objects that you call methods on. You can find all the methods in the [Ruby docs][ruby-doc.org-string] + +It's also worth knowing that strings can be created using single quotes (`'`) or double quotes (`"`). Single-quoted strings don't process ASCII escape codes(\n, \t etc.), and they don't do [string interpolation][ruby-for-beginners.rubymonstas.org-interpolation] while double-quoted does both. + +You can also create strings using the [heredoc syntax][ruby-heredoc] or using the `%q` and `%Q` helpers. + +[ruby-for-beginners.rubymonstas.org-interpolation]: http://ruby-for-beginners.rubymonstas.org/bonus/string_interpolation.html +[ruby-doc.org-string]: https://ruby-doc.org/core-2.7.0/String.html +[ruby-heredoc]: https://www.rubyguides.com/2018/11/ruby-heredoc/ + + diff --git a/exercises/concept/strings/.docs/hints.md b/exercises/concept/strings/.docs/hints.md new file mode 100644 index 0000000000..994bf81740 --- /dev/null +++ b/exercises/concept/strings/.docs/hints.md @@ -0,0 +1,25 @@ +# Hints + +### General + +- The [rubymostas strings guide][ruby-for-beginners.rubymonstas.org-strings] has a nice introduction to Ruby strings. +- The `String` object has many useful [built-in methods][docs-string-methods]. + +### 1. Get message from a log line + +- There are different ways to search for text in a string, which can be found on the [Ruby language official documentation][docs-string-methods]. +- There are [built in methods][strip-white-space] to strip white space. + +### 2. Get log level from a log line + +- Ruby `String` objects have a [method][downcase] to perform this operation. + +### 3. Reformat a log line + +- There are several ways to [concatenate strings][ruby-for-beginners.rubymonstas.org-strings], but the preferred one is usually [string interpolation][ruby-for-beginners.rubymonstas.org-strings] + +[ruby-for-beginners.rubymonstas.org-strings]: http://ruby-for-beginners.rubymonstas.org/built_in_classes/strings.html +[ruby-for-beginners.rubymonstas.org-interpolation]: http://ruby-for-beginners.rubymonstas.org/bonus/string_interpolation.html +[docs-string-methods]: https://ruby-doc.org/core-2.7.0/String.html +[strip-white-space]: https://ruby-doc.org/core-2.7.0/String.html#method-i-strip +[downcase]: https://ruby-doc.org/core-2.7.0/String.html#method-i-downcase diff --git a/exercises/concept/strings/.docs/instructions.md b/exercises/concept/strings/.docs/instructions.md new file mode 100644 index 0000000000..16dea14e04 --- /dev/null +++ b/exercises/concept/strings/.docs/instructions.md @@ -0,0 +1,47 @@ +# Instructions + +In this exercise you'll be processing log-lines. + +Each log line is a string formatted as follows: `"[]: "`. + +There are three different log levels: + +- `INFO` +- `WARNING` +- `ERROR` + +You have three tasks, each of which will take a log line and ask you to do something with it. + +### 1. Get message from a log line + +Implement a method to return a log line's message: + +```ruby +LogLineParser.message('[ERROR]: Invalid operation') +// Returns: "Invalid operation" +``` + +Any leading or trailing white space should be removed: + +```ruby +LogLineParser.message('[WARNING]: Disk almost full\r\n') +// Returns: "Disk almost full" +``` + +### 2. Get log level from a log line + +Implement a method to return a log line's log level, which should be returned in lowercase: + +```ruby +LogLineParser.log_level('[ERROR]: Invalid operation') +// Returns: "error" +``` + +### 3. Reformat a log line + +Implement a method that reformats the log line, putting the message first and the log level after it in parentheses: + +```ruby +LogLineParser.reformat('[INFO]: Operation completed') +// Returns: "Operation completed (info)" +``` diff --git a/exercises/concept/strings/.docs/introduction.md b/exercises/concept/strings/.docs/introduction.md new file mode 100644 index 0000000000..b50c12dd4f --- /dev/null +++ b/exercises/concept/strings/.docs/introduction.md @@ -0,0 +1,4 @@ +# Introduction + +A `String` in Ruby is an object that holds and manipulates an arbitrary sequence of bytes, typically representing characters. Strings are manipulated by calling the string's methods. + diff --git a/exercises/concept/strings/.meta/config.json b/exercises/concept/strings/.meta/config.json new file mode 100644 index 0000000000..bff9ecf46f --- /dev/null +++ b/exercises/concept/strings/.meta/config.json @@ -0,0 +1,8 @@ +{ + "contributors": [ + { + "github_username": "pvcarrera", + "exercism_username": "pvcarrera" + } + ] +} diff --git a/exercises/concept/strings/.meta/design.md b/exercises/concept/strings/.meta/design.md new file mode 100644 index 0000000000..69b4186ee4 --- /dev/null +++ b/exercises/concept/strings/.meta/design.md @@ -0,0 +1,41 @@ +# Design + +## Goal + +The goal of this exercise is to teach the student the basics of the Concept of Strings in [Ruby][ruby-doc.org-string]. + +## Things to teach + +- Know of the existence of the `String` object. +- Know how to create a string. +- Know of some basic string methods (like finding the index of a character at a position, or returning a part the string). +- Know how to do basic string interpolation. + +## Things not to teach + +- Using standard or custom format strings. +- Memory and performance characteristics. +- Strings can be a collection. + +## Concepts + +The Concepts this exercise unlocks are: + +- `strings-basic`: know of the existence of the `String` object; know of some basic functions (like looking up a character at a position, or slicing the string); know how to do basic string interpolation. + +## Prequisites + +There are no prerequisites. + +## Representer + +This exercise does not require any specific representation logic to be added to the [representer][representer]. + +## Analyzer + +This exercise does not require any specific logic to be added to the [analyzer][analyzer]. + +[analyzer]: https://github.com/exercism/ruby-analyzer +[representer]: https://github.com/exercism/ruby-representer +[ruby-doc.org-string]: https://ruby-doc.org/core-2.7.0/String.html + diff --git a/exercises/concept/strings/.meta/example.rb b/exercises/concept/strings/.meta/example.rb new file mode 100644 index 0000000000..3f6974f86e --- /dev/null +++ b/exercises/concept/strings/.meta/example.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module LogLineParser + def self.message(line) + line.slice(line.index(':') + 1, line.size).strip + end + + def self.log_level(line) + line.slice(1, line.index(']') - 1).downcase + end + + def self.reformat(line) + "#{self.message(line)} (#{self.log_level(line)})" + end +end diff --git a/exercises/concept/strings/log_line_parser.rb b/exercises/concept/strings/log_line_parser.rb new file mode 100644 index 0000000000..238d6f62fc --- /dev/null +++ b/exercises/concept/strings/log_line_parser.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module LogLineParser + def self.message(line) + raise NotImplementedError, 'Please implement the LogLineParser.message method' + end + + def self.log_level(line) + raise NotImplementedError, 'Please implement the LogLineParser.log_level method' + end + + def self.reformat(line) + raise NotImplementedError, 'Please implement the LogLineParser.reformat method' + end +end diff --git a/exercises/concept/strings/log_line_parser_test.rb b/exercises/concept/strings/log_line_parser_test.rb new file mode 100644 index 0000000000..0c8e1cb9be --- /dev/null +++ b/exercises/concept/strings/log_line_parser_test.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require 'minitest/autorun' +require_relative 'log_line_parser' + +class LogLineParserTest < Minitest::Test + def test_error_message + assert_equal 'Stack overflow', LogLineParser.message('[ERROR]: Stack overflow') + end + + def test_warning_message + assert_equal 'Disk almost full', LogLineParser.message('[WARNING]: Disk almost full') + end + + def test_info_message + assert_equal 'File moved', LogLineParser.message('[INFO]: File moved') + end + + def test_message_with_leading_and_trailing_space + assert_equal 'Timezone not set', LogLineParser.message("[WARNING]: \tTimezone not set \r\n") + end + + def test_error_log_level + assert_equal 'error', LogLineParser.log_level('[ERROR]: Disk full') + end + + def test_warning_log_level + assert_equal 'warning', LogLineParser.log_level('[WARNING]: Unsafe password') + end + + def test_info_log_level + assert_equal 'info', LogLineParser.log_level('[INFO]: Timezone changed') + end + + def test_erro_reformat + assert_equal 'Segmentation fault (error)', LogLineParser.reformat('[ERROR]: Segmentation fault') + end + + def test_warning_reformat + assert_equal 'Decreased performance (warning)', LogLineParser.reformat('[WARNING]: Decreased performance') + end + + def test_info_reformat + assert_equal 'Disk defragmented (info)', LogLineParser.reformat('[INFO]: Disk defragmented') + end + + def rest_reformat_with_leading_and_trailing_space + assert_equal 'Corrupt disk (error)', LogLineParser.reformat("[ERROR]: \t Corrupt disk\t \t \r\n") + end +end From 190012b03e9d448bd93b8e7e87350a5b95b7442e Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 21 Feb 2020 17:12:49 +0100 Subject: [PATCH 003/102] Rephrase the design document headers [Docs] Rephrase the design document headers --- exercises/concept/strings/.meta/design.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/concept/strings/.meta/design.md b/exercises/concept/strings/.meta/design.md index 69b4186ee4..dd0a01a657 100644 --- a/exercises/concept/strings/.meta/design.md +++ b/exercises/concept/strings/.meta/design.md @@ -4,14 +4,14 @@ The goal of this exercise is to teach the student the basics of the Concept of Strings in [Ruby][ruby-doc.org-string]. -## Things to teach +## Learning objectives - Know of the existence of the `String` object. - Know how to create a string. - Know of some basic string methods (like finding the index of a character at a position, or returning a part the string). - Know how to do basic string interpolation. -## Things not to teach +## Out of scope - Using standard or custom format strings. - Memory and performance characteristics. From 0b6c48b7d076e1211ebe464a92f6507c4719fda7 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Wed, 26 Feb 2020 13:35:25 +0100 Subject: [PATCH 004/102] Remove primary heading for documents in `.docs` folder --- exercises/concept/strings/.docs/after.md | 4 ---- exercises/concept/strings/.docs/hints.md | 2 -- exercises/concept/strings/.docs/instructions.md | 2 -- exercises/concept/strings/.docs/introduction.md | 3 --- 4 files changed, 11 deletions(-) diff --git a/exercises/concept/strings/.docs/after.md b/exercises/concept/strings/.docs/after.md index 921c22243c..493d294a0e 100644 --- a/exercises/concept/strings/.docs/after.md +++ b/exercises/concept/strings/.docs/after.md @@ -1,5 +1,3 @@ -# After - The key thing to remember about Ruby strings is that they are objects that you call methods on. You can find all the methods in the [Ruby docs][ruby-doc.org-string] It's also worth knowing that strings can be created using single quotes (`'`) or double quotes (`"`). Single-quoted strings don't process ASCII escape codes(\n, \t etc.), and they don't do [string interpolation][ruby-for-beginners.rubymonstas.org-interpolation] while double-quoted does both. @@ -9,5 +7,3 @@ You can also create strings using the [heredoc syntax][ruby-heredoc] or using th [ruby-for-beginners.rubymonstas.org-interpolation]: http://ruby-for-beginners.rubymonstas.org/bonus/string_interpolation.html [ruby-doc.org-string]: https://ruby-doc.org/core-2.7.0/String.html [ruby-heredoc]: https://www.rubyguides.com/2018/11/ruby-heredoc/ - - diff --git a/exercises/concept/strings/.docs/hints.md b/exercises/concept/strings/.docs/hints.md index 994bf81740..d890de9b9e 100644 --- a/exercises/concept/strings/.docs/hints.md +++ b/exercises/concept/strings/.docs/hints.md @@ -1,5 +1,3 @@ -# Hints - ### General - The [rubymostas strings guide][ruby-for-beginners.rubymonstas.org-strings] has a nice introduction to Ruby strings. diff --git a/exercises/concept/strings/.docs/instructions.md b/exercises/concept/strings/.docs/instructions.md index 16dea14e04..bb4c59fde4 100644 --- a/exercises/concept/strings/.docs/instructions.md +++ b/exercises/concept/strings/.docs/instructions.md @@ -1,5 +1,3 @@ -# Instructions - In this exercise you'll be processing log-lines. Each log line is a string formatted as follows: `"[]: "`. diff --git a/exercises/concept/strings/.docs/introduction.md b/exercises/concept/strings/.docs/introduction.md index b50c12dd4f..b2515ab7bf 100644 --- a/exercises/concept/strings/.docs/introduction.md +++ b/exercises/concept/strings/.docs/introduction.md @@ -1,4 +1 @@ -# Introduction - A `String` in Ruby is an object that holds and manipulates an arbitrary sequence of bytes, typically representing characters. Strings are manipulated by calling the string's methods. - From 0f91b1569a7fe7436cba6d00785744e9d1f72a9b Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Wed, 26 Feb 2020 16:35:03 +0100 Subject: [PATCH 005/102] Add docs/reference split * [Docs] Move implementing-a-concept-exercise.md to reference folder * [Docs] Move reference documents to docs folder * [Docs] Update to student-facing docs * [Docs] Add new issue template Co-Authored-By: Jeremy Walker Co-Authored-By: Victor Goff Co-authored-by: Sascha Mann --- reference/implementing-a-concept-exercise.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 reference/implementing-a-concept-exercise.md diff --git a/reference/implementing-a-concept-exercise.md b/reference/implementing-a-concept-exercise.md new file mode 100644 index 0000000000..59cd1f6f4e --- /dev/null +++ b/reference/implementing-a-concept-exercise.md @@ -0,0 +1,5 @@ +# How to implement an Ruby concept exercise + +TODO: describe how to implement a concept exercise for the Ruby track. For inspiration, check out the [C# version of this file][csharp-implementing]. + +[csharp-implementing]: ../../csharp/reference/implementing-a-concept-exercise.md From 9c47d6d20e23d76c7962a3a0ec06b7736bb65f8f Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Sun, 8 Mar 2020 20:23:46 +0100 Subject: [PATCH 006/102] Add concept implementation guide Ported from the C# track * Add concept exercise implementation guide * Update README status list * Use string literals instead of HTML entities --- reference/implementing-a-concept-exercise.md | 62 +++++++++++++++++++- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/reference/implementing-a-concept-exercise.md b/reference/implementing-a-concept-exercise.md index 59cd1f6f4e..de221d6264 100644 --- a/reference/implementing-a-concept-exercise.md +++ b/reference/implementing-a-concept-exercise.md @@ -1,5 +1,61 @@ -# How to implement an Ruby concept exercise +# How to implement a Ruby concept exercise -TODO: describe how to implement a concept exercise for the Ruby track. For inspiration, check out the [C# version of this file][csharp-implementing]. +This document describes how to implement a concept exercise for the Ruby track. As this document is generic, `` will be use as the placeholder for the name of the exercise in underscore-case (e.g. `string_interpolation`) -[csharp-implementing]: ../../csharp/reference/implementing-a-concept-exercise.md +Before implementing the exercise, please make sure you have a good understanding of what the exercise should be teaching (and what not). This information can be found in the exercise's GitHub issue. Having done this, please read the [Ruby concept exercises introduction][concept-exercises]. + +To implement a concept exercise, the following files must be created: + +
+languages
+└── ruby
+    └── exercises
+        └── concept
+            └── 
+                ├── .docs
+                |   ├── instructions.md
+                |   ├── introduction.md
+                |   ├── hints.md
+                |   └── after.md (optional)
+                ├── .meta
+                |   |── config.json
+                |   |── design.md
+                |   └── example.rb
+                ├── .rb
+                └── _test.rb
+
+ +## Step 1: adding track-specific files + +These files are specific to the Ruby track: + +- `.rb`. the stub implementation file, which is the starting point for students to work on the exercise. +- `_test.rb`: the test suite. +- `.meta/example.rb`: an example implementation that passes all the tests. + +## Step 2: adding common files + +How to create the files common to all tracks is described in the [how to implement a concept exercise document][how-to-implement-a-concept-exercise]. + +## Step 3: add analyzer (optional) + +Some exercises could benefit from having an exercise-specific [analyzer][analyzer]. If so, specify what analysis rules should be applied to this exercise and why. + +## Step 4: custom representation (optional) + +Some exercises could benefit from having an custom representation as generated by the [Ruby representer][representer]. If so, specify what changes to the representation should be applied and why. + +## Inspiration + +When implementing an exercise, it can be very useful to look at already implemented Ruby exercises like the [strings exercise][concept-exercise-strings]. You can also check the exercise's [general concepts documents][reference] to see if other languages have already implemented an exercise for that concept. + +## Help + +If you have any questions regarding implementing the exercise, please post them as comments in the exercise's GitHub issue. + +[analyzer]: https://github.com/exercism/ruby-analyzer +[representer]: https://github.com/exercism/ruby-representer +[concept-exercises]: ../exercises/concept/README.md +[how-to-implement-a-concept-exercise]: ../../../docs/maintainers/generic-how-to-implement-a-concept-exercise.md +[concept-exercise-strings]: ../exercises/concept/strings +[reference]: ../../../reference From c5b1c1f38166e76702f3798fa20fa2d2452deeaf Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 2 Apr 2020 15:48:36 +0200 Subject: [PATCH 007/102] Make after.md required --- reference/implementing-a-concept-exercise.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/implementing-a-concept-exercise.md b/reference/implementing-a-concept-exercise.md index de221d6264..2180f4f604 100644 --- a/reference/implementing-a-concept-exercise.md +++ b/reference/implementing-a-concept-exercise.md @@ -16,7 +16,7 @@ languages | ├── instructions.md | ├── introduction.md | ├── hints.md - | └── after.md (optional) + | └── after.md ├── .meta | |── config.json | |── design.md From d42839bef0bf6222a4a4f3c555d3a234845aff55 Mon Sep 17 00:00:00 2001 From: Jeremy Walker Date: Wed, 8 Apr 2020 12:27:51 +0100 Subject: [PATCH 008/102] Add Basics exercise * Add Basics exercise * Update languages/exercises/concept/basics/.docs/introduction.md Co-Authored-By: Erik Schierboom * Update languages/exercises/concept/basics/.docs/instructions.md Co-Authored-By: Erik Schierboom * Update languages/exercises/concept/basics/.docs/instructions.md Co-Authored-By: Erik Schierboom * Update languages/exercises/concept/basics/.docs/hints.md Co-Authored-By: Erik Schierboom * Update languages/exercises/concept/basics/.docs/hints.md Co-Authored-By: Erik Schierboom * Update languages/exercises/concept/basics/.docs/introduction.md Co-Authored-By: Erik Schierboom * Complete basic concept * Update languages/exercises/concept/basics/.meta/design.md Co-Authored-By: wolf99 * Update languages/config.json Co-Authored-By: Erik Schierboom * Add after.md * Add myself to the list of contributors * Update languages/exercises/concept/basics/.docs/after.md Co-Authored-By: wolf99 * Update languages/exercises/concept/basics/.docs/after.md Co-Authored-By: wolf99 * Update languages/exercises/concept/basics/.docs/after.md Co-Authored-By: wolf99 * Update languages/exercises/concept/basics/.docs/introduction.md Co-Authored-By: Victor Goff * Update languages/exercises/concept/basics/.docs/after.md Co-Authored-By: Victor Goff * Update fater.md * Update languages/exercises/concept/basics/.meta/design.md Co-Authored-By: Erik Schierboom * Update languages/config.json Co-Authored-By: Erik Schierboom * Update languages/exercises/concept/README.md Co-Authored-By: Erik Schierboom * Update languages/exercises/concept/basics/.docs/after.md Co-Authored-By: Erik Schierboom * Update languages/config.json Co-Authored-By: Erik Schierboom * Update languages/exercises/concept/basics/.docs/introduction.md Co-Authored-By: Jeremy Walker * Update languages/exercises/concept/basics/.docs/introduction.md * Update languages/exercises/concept/basics/.docs/introduction.md * Clarify wording in after around objects Co-authored-by: Erik Schierboom Co-authored-by: Pablo Vicente Co-authored-by: wolf99 Co-authored-by: Victor Goff --- exercises/concept/basics/.docs/after.md | 45 +++++++++++++++ exercises/concept/basics/.docs/hints.md | 30 ++++++++++ .../concept/basics/.docs/instructions.md | 42 ++++++++++++++ .../concept/basics/.docs/introduction.md | 55 +++++++++++++++++++ exercises/concept/basics/.meta/config.json | 12 ++++ exercises/concept/basics/.meta/design.md | 49 +++++++++++++++++ exercises/concept/basics/.meta/example.rb | 16 ++++++ exercises/concept/basics/lasagna.rb | 16 ++++++ exercises/concept/basics/lasagna_test.rb | 36 ++++++++++++ 9 files changed, 301 insertions(+) create mode 100644 exercises/concept/basics/.docs/after.md create mode 100644 exercises/concept/basics/.docs/hints.md create mode 100644 exercises/concept/basics/.docs/instructions.md create mode 100644 exercises/concept/basics/.docs/introduction.md create mode 100644 exercises/concept/basics/.meta/config.json create mode 100644 exercises/concept/basics/.meta/design.md create mode 100644 exercises/concept/basics/.meta/example.rb create mode 100644 exercises/concept/basics/lasagna.rb create mode 100644 exercises/concept/basics/lasagna_test.rb diff --git a/exercises/concept/basics/.docs/after.md b/exercises/concept/basics/.docs/after.md new file mode 100644 index 0000000000..4b79e721bd --- /dev/null +++ b/exercises/concept/basics/.docs/after.md @@ -0,0 +1,45 @@ +Ruby is a dynamic and strongly typed language. In dynamic languages the type of a variable or object is resolved at runtime, which means that its value or type can be changed up to the very last moment (when it gets parsed by the interpreter). +And what do we mean with strongly typed? Once we know the type of a variable or object, Ruby is strict about what you can do with it, for example: + +```ruby +x = '2' +y = x + 'n' +=> '2n' +``` + +**But** + +```ruby +x = '2' +y = x + 2 +=> TypeError (no implicit conversion of Integer into String) + +Remember, in Ruby everything is an object. Even classes are instances of the class `Class`. For example: + +```ruby +1.class +=> Integer + +Integer.is_a?(Object) +# => true + +Class.is_a?(Object) +# => true +``` + +This means that we can also define classes like this: + +```ruby +Car = Class.new do + def run + 'running' + end +end + +Car.new.run +=> 'running' +``` + +Finally, bear in mind that the `Integer` object holds values that may be defined as one or more (consecutive) digits and its methods support many of the [mathematical operators][integers-docs]. + +[integers-docs]: https://ruby-doc.org/core-2.7.0/Integer.html diff --git a/exercises/concept/basics/.docs/hints.md b/exercises/concept/basics/.docs/hints.md new file mode 100644 index 0000000000..69af121c25 --- /dev/null +++ b/exercises/concept/basics/.docs/hints.md @@ -0,0 +1,30 @@ +### 1. Define the expected oven time in minutes + +- You need to define a [constant][constant] which should contain the [integer][integers] value specified in the recipe. + +### 2. Calculate the remaining oven time in minutes + +- You need to define a [method][methods] with a single parameter for the actual time so far. +- You can [implicitly return an integer][return] from the method. +- You can use the [mathematical operator for subtraction][operators] to subtract values. + +### 3. Calculate the preparation time in minutes + +- You need to define a [method][methods] with a single parameter for the number of layers. +- You can [implicitly return an integer][return] from the method. +- You can use the [mathematical operator for multiplicaton][operators] to multiply values. +- You could define an extra constant for the time in minutes per layer, or use a "magic number" in the code. + +### 4. Calculate the total working time in minutes + +- You need to define a [method][methods] with two named parameters: `number_of_layers` and `actual_minutes_in_oven`. +- You can [implicitly return an integer][return] from the method. +- You can [invoke][invocation] one of the other methods you've defined previously. +- You can use the [mathematical operator for addition][operators] to add values. + +[methods]: https://launchschool.com/books/ruby/read/methods +[return]: https://www.freecodecamp.org/news/idiomatic-ruby-writing-beautiful-code-6845c830c664/ +[operators]: https://www.w3resource.com/ruby/ruby-arithmetic-operators.php +[constants]: https://www.rubyguides.com/2017/07/ruby-constants/ +[invocation]: http://ruby-for-beginners.rubymonstas.org/objects/calling.html +[integers]: https://ruby-doc.org/core-2.7.0/Integer.html diff --git a/exercises/concept/basics/.docs/instructions.md b/exercises/concept/basics/.docs/instructions.md new file mode 100644 index 0000000000..01345990ff --- /dev/null +++ b/exercises/concept/basics/.docs/instructions.md @@ -0,0 +1,42 @@ +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 `Lasagna::EXPECTED_MINUTES_IN_OVEN` constant that returns how many minutes the lasagna should be in the oven. According to the cooking book, the expected oven time in minutes is 40: + +```ruby +Lasagna::EXPECTED_MINUTES_IN_OVEN +# => 40 +``` + +### 2. Calculate the remaining oven time in minutes + +Define the `Lasagna#remaining_minutes_in_oven` method 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. + +```ruby +lasagna = Lasagna.new +lasagna.remaining_minutes_in_oven(30) +# => 10 +``` + +### 3. Calculate the preparation time in minutes + +Define the `Lasagna#preparation_time_in_minutes` method 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. + +```ruby +lasagna = Lasagna.new +lasagna.preparation_time_in_minutes(2) +# => 4 +``` + +### 4. Calculate the total working time in minutes + +Define the `Lasagna#total_time_in_minutes` method that takes two named parameters: the `number_of_layers` parameter is the number of layers you added to the lasagna, and the `actual_minutes_in_oven` 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. + +```ruby +lasagna = Lasagna.new +lasagna.total_time_in_minutes(number_of_layers: 3, actual_minutes_in_oven: 20); +# => 26 +``` diff --git a/exercises/concept/basics/.docs/introduction.md b/exercises/concept/basics/.docs/introduction.md new file mode 100644 index 0000000000..7aaf07ea71 --- /dev/null +++ b/exercises/concept/basics/.docs/introduction.md @@ -0,0 +1,55 @@ +Ruby is a dynamic [object-oriented language]. Everything in Ruby is an [object][object]. + +There are two primary ways to assign objects to names in Ruby - using variables or constants. Variables are always written in [snake case][snake-case]. A variable can reference different objects over its lifetime. For example, `my_first_variable` can be defined and redefined many times using the `=` operator: + +```ruby +my_first_variable = 1 +my_first_variable = "Some string" +my_first_variable = SomeComplexObject.new +``` + +Constants, however, are meant to be assigned once. They must start with capital letters and are normally written in block capitals with words separated by underscores. For example: + +```ruby +MY_FIRST_CONSTANT = 10 + +# Redefining not allowed +# MY_FIRST_CONSTANT = "Some String" +``` + +Ruby is organised into classes. Classes are defined using the `class` keyword followed by the name of the class. Objects are generally created by instantiating classes using the `.new` method. For example: + +```ruby +# Define the class +class Calculator + #... +end + +# Create an instance of it and assign it to a variable +my_first_calc = Calculator.new +``` + +Units of functionality are encapsulated in methods - similar to _functions_ in other languages. A method can optionally be defined with positional arguments, and/or keyword arguments that are defined and called using the `:` syntax. Methods either implicitly return the result of the last evaluated statement, or can explicitly return an object via the `return` keyword. Methods are invoked using `.` syntax. + +```ruby +class Calculator + + # Unnamed params + def add(num1, num2) + return num1 + num2 # Explicit return + end + + # Named params + def multiply(num1:, num2:) + num1 * num2 # Implicit return + end +end + +calc = Calculator.new +calc.add(1, 3) +calc.multiply(num1: 2, num_2: 5) +``` + +[object-oriented-programming]: https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/oothinking.html +[object]: ../../../../../../reference/concepts/objects.md +[snake-case]: https://en.wikipedia.org/wiki/Snake_case diff --git a/exercises/concept/basics/.meta/config.json b/exercises/concept/basics/.meta/config.json new file mode 100644 index 0000000000..069b69a61b --- /dev/null +++ b/exercises/concept/basics/.meta/config.json @@ -0,0 +1,12 @@ +{ + "contributors": [ + { + "github_username": "iHiD", + "exercism_username": "iHiD" + }, + { + "github_username": "pvcarrera", + "exercism_username": "pvcarrera" + } + ] +} diff --git a/exercises/concept/basics/.meta/design.md b/exercises/concept/basics/.meta/design.md new file mode 100644 index 0000000000..d566426ae6 --- /dev/null +++ b/exercises/concept/basics/.meta/design.md @@ -0,0 +1,49 @@ +# Design + +## Goal + +The goal of this exercise is to teach the student the basics of programming in Ruby. + +## Learning objectives + +- Know what a variable is. +- Know how to define a variable. +- Know how to update a variable. +- Know how to define a method. +- Know how to return a value from a method. +- Know how to call a method. +- Know how to call a method with named parameters. +- Know that methods must be defined in classes. +- Know how to define an integer. +- Know how to use mathematical operators on integers. +- Know how to use constants + +## Out of scope + +- Memory and performance characteristics. +- Method overloads. +- Lambdas. +- Optional parameters. +- Organizing methods in namespaces. +- Visibility. + +## Concepts + +The Concepts this exercise unlocks are: + +- `basics`: know what a variable is; know how to define a variable; know how to update a variable; know how to use type inference for variables; know how to define a method; know how to return a value from a method; know how to call a method; know that methods must be defined in classes; know about the `public` access modifier; know about the `static` modifier; know how to define an integer; know how to use mathematical operators on integers; know how to define an integer; know how to use mathematical operators on integers. + +## Prequisites + +There are no prerequisites. + +## Representer + +This exercise does not require any specific representation logic to be added to the [representer][representer]. + +## Analyzer + +This exercise does not require any specific logic to be added to the [analyzer][analyzer]. + +[analyzer]: https://github.com/exercism/ruby-analyzer +[representer]: https://github.com/exercism/ruby-representer diff --git a/exercises/concept/basics/.meta/example.rb b/exercises/concept/basics/.meta/example.rb new file mode 100644 index 0000000000..28d835ff23 --- /dev/null +++ b/exercises/concept/basics/.meta/example.rb @@ -0,0 +1,16 @@ +class Lasagna + EXPECTED_MINUTES_IN_OVEN = 40 + PREPARATION_MINUTES_PER_LAYER = 2 + + def remaining_minutes_in_oven(actual_minutes_in_oven) + EXPECTED_MINUTES_IN_OVEN - actual_minutes_in_oven + end + + def preparation_time_in_minutes(layers) + layers * PREPARATION_MINUTES_PER_LAYER + end + + def total_time_in_minutes(number_of_layers:, actual_minutes_in_oven:) + preparation_time_in_minutes(number_of_layers) + actual_minutes_in_oven + end +end diff --git a/exercises/concept/basics/lasagna.rb b/exercises/concept/basics/lasagna.rb new file mode 100644 index 0000000000..ae6b9703c9 --- /dev/null +++ b/exercises/concept/basics/lasagna.rb @@ -0,0 +1,16 @@ +class Lasagna + EXPECTED_MINUTES_IN_OVEN = 40 + PREPARATION_MINUTES_PER_LAYER = 2 + + def remaining_minutes_in_oven(actual_minutes_in_oven) + raise NotImplementedError, 'Please implement the remaining_minutes_in_oven method' + end + + def preperation_time_in_minutes(layers) + raise NotImplementedError, 'Please implement the preperation_time_in_minutes method' + end + + def total_time_in_minutes(number_of_layers:, actual_minutes_in_oven:) + raise NotImplementedError, 'Please implement the total_time_in_minutes method' + end +end diff --git a/exercises/concept/basics/lasagna_test.rb b/exercises/concept/basics/lasagna_test.rb new file mode 100644 index 0000000000..dc9ab73450 --- /dev/null +++ b/exercises/concept/basics/lasagna_test.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'minitest/autorun' +require_relative 'lasagna' + +class LasagnaTest < Minitest::Test + def test_expected_minutes_in_oven + assert_equal 40, Lasagna::EXPECTED_MINUTES_IN_OVEN + end + + def test_remaining_minutes_in_oven + assert_equal 15, Lasagna.new.remaining_minutes_in_oven(25) + end + + def test_preparation_time_in_minutes_with_one_layer + assert_equal 2, Lasagna.new.preparation_time_in_minutes(1) + end + + def test_preparation_time_in_minutes_with_multiple_layers + assert_equal 8, Lasagna.new.preparation_time_in_minutes(4) + end + + def test_total_time_in_minutes_for_one_layer + assert_equal 32, Lasagna.new.total_time_in_minutes( + number_of_layers: 1, + actual_minutes_in_oven: 30 + ) + end + + def test_total_time_in_minutes_for_multiple_layer + assert_equal 16, Lasagna.new.total_time_in_minutes( + number_of_layers: 4, + actual_minutes_in_oven: 8 + ) + end +end From aaf0998fafa75d1118e6e6a8dd8b14f22aa1cc05 Mon Sep 17 00:00:00 2001 From: Jeremy Walker Date: Thu, 9 Apr 2020 14:18:06 +0100 Subject: [PATCH 009/102] Add source and versioninfo to exercise config Co-authored-by: Sascha Mann Co-authored-by: Erik Schierboom --- reference/implementing-a-concept-exercise.md | 1 + 1 file changed, 1 insertion(+) diff --git a/reference/implementing-a-concept-exercise.md b/reference/implementing-a-concept-exercise.md index 2180f4f604..601fdef8e2 100644 --- a/reference/implementing-a-concept-exercise.md +++ b/reference/implementing-a-concept-exercise.md @@ -16,6 +16,7 @@ languages | ├── instructions.md | ├── introduction.md | ├── hints.md + | ├── source.md (required if there are third-party sources) | └── after.md ├── .meta | |── config.json From 6054c7a89b50e945b82994bd5c6e91d2790e4290 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 10 Apr 2020 14:06:33 +0200 Subject: [PATCH 010/102] Add reference to required reading in implementing guide [Docs] Add reference to required reading in implementing guide --- reference/implementing-a-concept-exercise.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/reference/implementing-a-concept-exercise.md b/reference/implementing-a-concept-exercise.md index 601fdef8e2..e3fa482dc6 100644 --- a/reference/implementing-a-concept-exercise.md +++ b/reference/implementing-a-concept-exercise.md @@ -1,6 +1,14 @@ # How to implement a Ruby concept exercise -This document describes how to implement a concept exercise for the Ruby track. As this document is generic, `` will be use as the placeholder for the name of the exercise in underscore-case (e.g. `string_interpolation`) +This document describes how to implement a concept exercise for the Ruby track. + +**Please please please read the docs before starting.** Posting PRs without reading these docs will be a lot more frustrating for you during the review cycle, and exhaust Exercism's maintainers' time. So, before diving into the implementation, please read the following documents: + +- [The features of v3][docs-features-of-v3]. +- [Rationale for v3][docs-rationale-for-v3]. +- [What are concept exercise and how they are structured?][docs-concept-exercises] + +As this document is generic, `` will be use as the placeholder for the name of the exercise in underscore-case (e.g. `string_interpolation`) Before implementing the exercise, please make sure you have a good understanding of what the exercise should be teaching (and what not). This information can be found in the exercise's GitHub issue. Having done this, please read the [Ruby concept exercises introduction][concept-exercises]. @@ -58,5 +66,8 @@ If you have any questions regarding implementing the exercise, please post them [representer]: https://github.com/exercism/ruby-representer [concept-exercises]: ../exercises/concept/README.md [how-to-implement-a-concept-exercise]: ../../../docs/maintainers/generic-how-to-implement-a-concept-exercise.md +[docs-concept-exercises]: ../../../docs/concept-exercises.md +[docs-rationale-for-v3]: ../../../docs/rationale-for-v3.md +[docs-features-of-v3]: ../../../docs/features-of-v3.md [concept-exercise-strings]: ../exercises/concept/strings [reference]: ../../../reference From 4a2a42b9c939bf5d4474c8b4ce72f450c4d97e0b Mon Sep 17 00:00:00 2001 From: Victor Goff Date: Sat, 11 Apr 2020 14:02:30 -0400 Subject: [PATCH 011/102] exercise author credit for basic and string ref: #1190 /cc @ihid @pvcarrera --- exercises/concept/basics/.meta/config.json | 2 +- exercises/concept/strings/.meta/config.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/concept/basics/.meta/config.json b/exercises/concept/basics/.meta/config.json index 069b69a61b..3ee737416f 100644 --- a/exercises/concept/basics/.meta/config.json +++ b/exercises/concept/basics/.meta/config.json @@ -1,5 +1,5 @@ { - "contributors": [ + "authors": [ { "github_username": "iHiD", "exercism_username": "iHiD" diff --git a/exercises/concept/strings/.meta/config.json b/exercises/concept/strings/.meta/config.json index bff9ecf46f..db52a259fb 100644 --- a/exercises/concept/strings/.meta/config.json +++ b/exercises/concept/strings/.meta/config.json @@ -1,5 +1,5 @@ { - "contributors": [ + "authors": [ { "github_username": "pvcarrera", "exercism_username": "pvcarrera" From 47049bc6df4080c3e6c3f0d87c11cdb4fb51f386 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Tue, 14 Apr 2020 15:49:14 +0200 Subject: [PATCH 012/102] Add reference to Concept Exercise Anatomy video [Docs] Add reference to Concept Exercise Anatomy video --- reference/implementing-a-concept-exercise.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/reference/implementing-a-concept-exercise.md b/reference/implementing-a-concept-exercise.md index e3fa482dc6..19c8cb51f4 100644 --- a/reference/implementing-a-concept-exercise.md +++ b/reference/implementing-a-concept-exercise.md @@ -8,6 +8,10 @@ This document describes how to implement a concept exercise for the Ruby track. - [Rationale for v3][docs-rationale-for-v3]. - [What are concept exercise and how they are structured?][docs-concept-exercises] +Please also watch the following video: + +- [The Anatomy of a Concept Exercise][anatomy-of-a-concept-exercise]. + As this document is generic, `` will be use as the placeholder for the name of the exercise in underscore-case (e.g. `string_interpolation`) Before implementing the exercise, please make sure you have a good understanding of what the exercise should be teaching (and what not). This information can be found in the exercise's GitHub issue. Having done this, please read the [Ruby concept exercises introduction][concept-exercises]. @@ -69,5 +73,6 @@ If you have any questions regarding implementing the exercise, please post them [docs-concept-exercises]: ../../../docs/concept-exercises.md [docs-rationale-for-v3]: ../../../docs/rationale-for-v3.md [docs-features-of-v3]: ../../../docs/features-of-v3.md +[anatomy-of-a-concept-exercise]: https://www.youtube.com/watch?v=gkbBqd7hPrA [concept-exercise-strings]: ../exercises/concept/strings [reference]: ../../../reference From 5e66d116508036c482fa8709346c5fc7789c2f9b Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Tue, 14 Apr 2020 16:02:21 +0200 Subject: [PATCH 013/102] Skip analyzer and representer steps if unclear --- reference/implementing-a-concept-exercise.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/reference/implementing-a-concept-exercise.md b/reference/implementing-a-concept-exercise.md index 19c8cb51f4..4252d9e98f 100644 --- a/reference/implementing-a-concept-exercise.md +++ b/reference/implementing-a-concept-exercise.md @@ -54,10 +54,14 @@ How to create the files common to all tracks is described in the [how to impleme Some exercises could benefit from having an exercise-specific [analyzer][analyzer]. If so, specify what analysis rules should be applied to this exercise and why. +Skip this step if you're not sure what to do. + ## Step 4: custom representation (optional) Some exercises could benefit from having an custom representation as generated by the [Ruby representer][representer]. If so, specify what changes to the representation should be applied and why. +Skip this step if you're not sure what to do. + ## Inspiration When implementing an exercise, it can be very useful to look at already implemented Ruby exercises like the [strings exercise][concept-exercise-strings]. You can also check the exercise's [general concepts documents][reference] to see if other languages have already implemented an exercise for that concept. From ebe2580811eb1498b1ba532b045563f97582ca7e Mon Sep 17 00:00:00 2001 From: Viktor Date: Tue, 14 Apr 2020 21:56:14 +0200 Subject: [PATCH 014/102] Add Resistor Color Duo concepts --- .../exercise-concepts/resistor-color-duo.md | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 reference/exercise-concepts/resistor-color-duo.md diff --git a/reference/exercise-concepts/resistor-color-duo.md b/reference/exercise-concepts/resistor-color-duo.md new file mode 100644 index 0000000000..aa6cb625e7 --- /dev/null +++ b/reference/exercise-concepts/resistor-color-duo.md @@ -0,0 +1,52 @@ +# Concepts of Resistor Color Duo + +## General + + [Example solution](https://github.com/exercism/ruby/blob/master/exercises/resistor-color-duo/.meta/solutions/resistor_color_duo.rb) + +- Classes: + - Defining classes +- Methods: + - Defining methods + - Arguments + - Return values +- Strings: + - What is a `String` +- Class methods: + - How to define a class method + +Depending on the approach either: +- Hashes: + - How to initialize/create a hash + - How to access it's values + +or +- Arrays: + - How to create an `Array` + - What are indexes and how can they be useful + - How to get the index of a value that's stored in an `Array` + +### Approach: use string interpolation (positional approach) + +- `String` interpolation +- How to get the `Integer` representation of a `String` + +### Approach: Using `Enumerable` methods + +- Loops: + - What it is + - How it works + - `Enumerable` methods and finding the appropriate one + - Return value of `Enumerable` methods +- Blocks: + - What blocks are + - How to use them with `Enumerable` methods + - How to chain method calls to blocks +- Arrays: + - How to take the first `n` elements form an `Array` +- Strings: + - How to get the `Integer` representation of a `String` + +### Approach: `first_value * 10 + second_value` + +- No special requirements other than the requirements mentioned in the general section From 7f14e3a704673932edde65d95839ab1c71a0c48c Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 16 Apr 2020 09:48:25 +0200 Subject: [PATCH 015/102] Format using Prettier [Docs] Format using Prettier --- exercises/concept/basics/.docs/after.md | 4 ++-- .../concept/basics/.docs/introduction.md | 2 +- exercises/concept/strings/.meta/design.md | 1 - .../exercise-concepts/nucleotide-count.md | 2 +- .../exercise-concepts/resistor-color-duo.md | 24 ++++++++++--------- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/exercises/concept/basics/.docs/after.md b/exercises/concept/basics/.docs/after.md index 4b79e721bd..9b14ae5c43 100644 --- a/exercises/concept/basics/.docs/after.md +++ b/exercises/concept/basics/.docs/after.md @@ -9,7 +9,7 @@ y = x + 'n' **But** -```ruby +````ruby x = '2' y = x + 2 => TypeError (no implicit conversion of Integer into String) @@ -25,7 +25,7 @@ Integer.is_a?(Object) Class.is_a?(Object) # => true -``` +```` This means that we can also define classes like this: diff --git a/exercises/concept/basics/.docs/introduction.md b/exercises/concept/basics/.docs/introduction.md index 7aaf07ea71..bef0b83a5f 100644 --- a/exercises/concept/basics/.docs/introduction.md +++ b/exercises/concept/basics/.docs/introduction.md @@ -29,7 +29,7 @@ end my_first_calc = Calculator.new ``` -Units of functionality are encapsulated in methods - similar to _functions_ in other languages. A method can optionally be defined with positional arguments, and/or keyword arguments that are defined and called using the `:` syntax. Methods either implicitly return the result of the last evaluated statement, or can explicitly return an object via the `return` keyword. Methods are invoked using `.` syntax. +Units of functionality are encapsulated in methods - similar to _functions_ in other languages. A method can optionally be defined with positional arguments, and/or keyword arguments that are defined and called using the `:` syntax. Methods either implicitly return the result of the last evaluated statement, or can explicitly return an object via the `return` keyword. Methods are invoked using `.` syntax. ```ruby class Calculator diff --git a/exercises/concept/strings/.meta/design.md b/exercises/concept/strings/.meta/design.md index dd0a01a657..4c5bd05a82 100644 --- a/exercises/concept/strings/.meta/design.md +++ b/exercises/concept/strings/.meta/design.md @@ -38,4 +38,3 @@ This exercise does not require any specific logic to be added to the [analyzer][ [analyzer]: https://github.com/exercism/ruby-analyzer [representer]: https://github.com/exercism/ruby-representer [ruby-doc.org-string]: https://ruby-doc.org/core-2.7.0/String.html - diff --git a/reference/exercise-concepts/nucleotide-count.md b/reference/exercise-concepts/nucleotide-count.md index ce28e936a6..2b98ea2305 100644 --- a/reference/exercise-concepts/nucleotide-count.md +++ b/reference/exercise-concepts/nucleotide-count.md @@ -43,6 +43,6 @@ - Use Regex to validate the input. ## Approach: Use collections + String#count. + - Similar to the previous approach but using `String#count` and `String#size` to validate the input. - For the input validation part it's also possible to use array difference to remove nucleotides from the input resulting in an empty collection for the valid inputs. - diff --git a/reference/exercise-concepts/resistor-color-duo.md b/reference/exercise-concepts/resistor-color-duo.md index aa6cb625e7..bb59092d44 100644 --- a/reference/exercise-concepts/resistor-color-duo.md +++ b/reference/exercise-concepts/resistor-color-duo.md @@ -2,7 +2,7 @@ ## General - [Example solution](https://github.com/exercism/ruby/blob/master/exercises/resistor-color-duo/.meta/solutions/resistor_color_duo.rb) +[Example solution](https://github.com/exercism/ruby/blob/master/exercises/resistor-color-duo/.meta/solutions/resistor_color_duo.rb) - Classes: - Defining classes @@ -16,15 +16,17 @@ - How to define a class method Depending on the approach either: + - Hashes: - How to initialize/create a hash - How to access it's values or + - Arrays: - - How to create an `Array` - - What are indexes and how can they be useful - - How to get the index of a value that's stored in an `Array` + - How to create an `Array` + - What are indexes and how can they be useful + - How to get the index of a value that's stored in an `Array` ### Approach: use string interpolation (positional approach) @@ -34,14 +36,14 @@ or ### Approach: Using `Enumerable` methods - Loops: - - What it is - - How it works - - `Enumerable` methods and finding the appropriate one - - Return value of `Enumerable` methods + - What it is + - How it works + - `Enumerable` methods and finding the appropriate one + - Return value of `Enumerable` methods - Blocks: - - What blocks are - - How to use them with `Enumerable` methods - - How to chain method calls to blocks + - What blocks are + - How to use them with `Enumerable` methods + - How to chain method calls to blocks - Arrays: - How to take the first `n` elements form an `Array` - Strings: From d61acd45cabe564f0deed605f7491fb918e67155 Mon Sep 17 00:00:00 2001 From: Viktor Date: Fri, 17 Apr 2020 01:21:44 +0200 Subject: [PATCH 016/102] New Concept exercise: floating-point-numbers * Add floats-concept-exercise * Update languages/exercises/concept/floating-point-numbers/.docs/instructions.md * Update languages/exercises/concept/floating-point-numbers/.meta/design.md Co-Authored-By: Victor Goff * Update languages/exercises/concept/floating-point-numbers/.docs/after.md * Update languages/exercises/concept/floating-point-numbers/.docs/instructions.md * Update * Add `loop` loop and rename concept from while-loops to loops * Update languages/exercises/concept/floating-point-numbers/.docs/after.md * Update example * Add examples for loops * Fix prettier checks Co-authored-by: Victor Goff Co-authored-by: Jeremy Walker --- .../floating-point-numbers/.docs/after.md | 53 +++++++++ .../floating-point-numbers/.docs/hints.md | 13 +++ .../.docs/instructions.md | 41 +++++++ .../.docs/introduction.md | 12 ++ .../floating-point-numbers/.meta/config.json | 9 ++ .../floating-point-numbers/.meta/design.md | 42 +++++++ .../floating-point-numbers/.meta/example.rb | 39 +++++++ .../floating-point-numbers/savings_account.rb | 13 +++ .../savings_account_test.rb | 105 ++++++++++++++++++ 9 files changed, 327 insertions(+) create mode 100644 exercises/concept/floating-point-numbers/.docs/after.md create mode 100644 exercises/concept/floating-point-numbers/.docs/hints.md create mode 100644 exercises/concept/floating-point-numbers/.docs/instructions.md create mode 100644 exercises/concept/floating-point-numbers/.docs/introduction.md create mode 100644 exercises/concept/floating-point-numbers/.meta/config.json create mode 100644 exercises/concept/floating-point-numbers/.meta/design.md create mode 100644 exercises/concept/floating-point-numbers/.meta/example.rb create mode 100644 exercises/concept/floating-point-numbers/savings_account.rb create mode 100644 exercises/concept/floating-point-numbers/savings_account_test.rb diff --git a/exercises/concept/floating-point-numbers/.docs/after.md b/exercises/concept/floating-point-numbers/.docs/after.md new file mode 100644 index 0000000000..a31d87ed0c --- /dev/null +++ b/exercises/concept/floating-point-numbers/.docs/after.md @@ -0,0 +1,53 @@ +A floating-point number is a number with zero or more digits behind the decimal separator. Examples are `4.0`, `0.1`, `3.14`, `-6.4` `16.984025` and `1024.0`. In Ruby, floating-point numbers are implemented through the [Float](https://ruby-doc.org/core-2.7.0/Float.html) class. + +You can find a short introduction to floating-point numbers at [0.30000000000000004.com][0.30000000000000004.com]. + +The [Float Toy page][evanw.github.io-float-toy] has a nice, graphical explanation how a floating-point numbers' bits are converted to an actual floating-point value. + +To repeatedly execute logic, one can use loops. In this example the `while` loop is useful because it keeps on looping _while_ a condition evaluates to some truthy value (i.e. not `false` or `nil`). Ruby implements a loop similar to the `while` loop. It's called the `until` loop, and you've probably guessed what it does. It keeps looping _until_ a boolean condition evaluates to `true`. In some languages, to make a piece of code execute an unlimited number of times, constructs like `while true` are used. In Ruby, the `loop` loop exists for that purpose. Even though the `loop` loop does not depend on a single condition, it can be canceled by using a `return` or `break` keyword. + +The `#years_before_desired_balance` method from the previous exercise could have been written by using any of the three mentioned loops: + +### `while` + +```ruby +def self.years_before_desired_balance(current_balance, desired_balance) + years = 0 + while current_balance < desired_balance + current_balance = annual_balance_update(current_balance) + years += 1 + end + years +end +``` + +### `until` + +```ruby +def self.years_before_desired_balance(current_balance, desired_balance) + years = 0 + until current_balance >= desired_balance + current_balance = annual_balance_update(current_balance) + years += 1 + end + years +end +``` + +### `loop` + +```ruby +def self.years_before_desired_balance(current_balance, desired_balance) + years = 0 + loop do + current_balance = annual_balance_update(current_balance) + years += 1 + return years if current_balance >= desired_balance + end +end +``` + +As you have probably noticed, Ruby has no increment operator (`i++`) like some other languages do. Instead, constructs like `i += 1` (which is equal to `i = i + 1`) can be used. + +[0.30000000000000004.com]: https://0.30000000000000004.com/ +[evanw.github.io-float-toy]: https://evanw.github.io/float-toy/ diff --git a/exercises/concept/floating-point-numbers/.docs/hints.md b/exercises/concept/floating-point-numbers/.docs/hints.md new file mode 100644 index 0000000000..b733bcec70 --- /dev/null +++ b/exercises/concept/floating-point-numbers/.docs/hints.md @@ -0,0 +1,13 @@ +### General + +### 1. Calculate the interest rate + +- Using an `if` or `case` statement can be useful when checking conditions. + +### 2. Calculate the annual balance update + +- When calculating the annual yield, it might be useful to temporarily convert a negative balance to a positive one. The `Float` class has a method to convert both positive and negative values to their absolute value. + +### 3. Calculate the years before reaching the desired balance + +- To calculate the years, one can keep looping until the desired balance is reached. diff --git a/exercises/concept/floating-point-numbers/.docs/instructions.md b/exercises/concept/floating-point-numbers/.docs/instructions.md new file mode 100644 index 0000000000..11a49a9d19 --- /dev/null +++ b/exercises/concept/floating-point-numbers/.docs/instructions.md @@ -0,0 +1,41 @@ +In this exercise you'll be working with savings accounts. Each year, the balance of a savings account is updated based on the interest rate. The interest rate the bank gives depends on the amount of money in the accounts (its balance): + +- -3.213% for a negative balance. +- 0.5% for a positive balance less than `1000` dollars. +- 1.621% for a positive balance greater or equal than `1000` dollars and less than `5000` dollars. +- 2.475% for a positive balance greater or equal than `5000` dollars. + +You have three tasks, each of which will deal the balance and its interest rate. + +### 1. Calculate the interest rate + +Implement the `SavingsAccount.interest_rate` method to calculate the interest rate based on the specified balance: + +```ruby +SavingsAccount.interest_rate(200.75) +#=> 0.5 +``` + +Note that the value returned is an instance of `Float`. + +### 2. Calculate the annual balance update + +Implement the `SavingsAccount.annual_balance_update` method to calculate the annual balance update, taking into account the interest rate: + +```ruby +SavingsAccount.annual_balance_update(200.75) +#=> 201.75375 +``` + +Note that the value returned is an instance of `Float`. + +### 3. Calculate the years before reaching the desired balance + +Implement the `SavingsAccount.years_before_desired_balance` method to calculate the minimum number of years required to reach the desired balance: + +```ruby +SavingsAccount.years_before_desired_balance(200.75, 214.88) +#=> 14 +``` + +Note that the value returned is an instance of `Integer`. diff --git a/exercises/concept/floating-point-numbers/.docs/introduction.md b/exercises/concept/floating-point-numbers/.docs/introduction.md new file mode 100644 index 0000000000..050095f094 --- /dev/null +++ b/exercises/concept/floating-point-numbers/.docs/introduction.md @@ -0,0 +1,12 @@ +A floating-point number is a number with zero or more digits behind the decimal separator. Examples are `4.0`, `0.1`, `3.14`, `-6.4` `16.984025` and `1024.0`. +In Ruby, floating-point numbers are implemented through the [Float](https://ruby-doc.org/core-2.7.0/Float.html) class. + +In this exercise you may also want to use a loop. There are several ways to write loops in Ruby, one of them is the `while` loop: + +```ruby +counter = 0 + +while counter < 5 + counter += 1 +end +``` diff --git a/exercises/concept/floating-point-numbers/.meta/config.json b/exercises/concept/floating-point-numbers/.meta/config.json new file mode 100644 index 0000000000..3afe01e988 --- /dev/null +++ b/exercises/concept/floating-point-numbers/.meta/config.json @@ -0,0 +1,9 @@ +{ + "contributors": [ + { + "github_username": "dvik1950", + "exercism_username": "dvik1950" + } + ], + "forked_from": ["csharp/floating-point-numbers"] +} diff --git a/exercises/concept/floating-point-numbers/.meta/design.md b/exercises/concept/floating-point-numbers/.meta/design.md new file mode 100644 index 0000000000..0d28f2a147 --- /dev/null +++ b/exercises/concept/floating-point-numbers/.meta/design.md @@ -0,0 +1,42 @@ +# Design + +## Goal + +The goal of this exercise is to teach the student the concept of floating-point numbers and introduce them to loops. + +## Learning objectives + +- Know about the [Float][float-class] class and some of its methods. +- Know how to write a `while`, `until` and `loop` loop. + +## Out of scope + +- Parsing floating-point types from strings. +- Converting floating-point types to strings. +- Using standard or custom format strings. + +## Concepts + +The Concepts this exercise unlocks are: + +- `floating-point-numbers` +- `loops`: know how to write a `while`, `until` and `loop` loop. + +## Prerequisites + +This exercise's prerequisite concepts are: + +- `numbers`: define numbers and apply arithmetic and boolean logic to them. +- `conditionals`: conditionally execute code based on value of floating-point numbers. + +## Representer + +This exercise does not require any specific representation logic to be added to the [representer][representer]. + +## Analyzer + +This exercise does not require any specific logic to be added to the [analyzer][analyzer]. + +[float-class]: https://ruby-doc.org/core-2.7.0/Float.html +[analyzer]: https://github.com/exercism/ruby-analyzer +[representer]: https://github.com/exercism/ruby-representer diff --git a/exercises/concept/floating-point-numbers/.meta/example.rb b/exercises/concept/floating-point-numbers/.meta/example.rb new file mode 100644 index 0000000000..2a3c84876e --- /dev/null +++ b/exercises/concept/floating-point-numbers/.meta/example.rb @@ -0,0 +1,39 @@ +module SavingsAccount + + NEGATIVE_RATE = -3.213 + SMALL_POSITIVE_RATE = 0.5 + MEDIUM_POSITIVE_RATE = 1.621 + LARGE_POSITIVE_RATE = 2.475 + + def self.interest_rate(balance) + if balance.negative? + NEGATIVE_RATE + elsif balance < 1000 + SMALL_POSITIVE_RATE + elsif balance < 5000 + MEDIUM_POSITIVE_RATE + else + LARGE_POSITIVE_RATE + end + end + + def self.annual_balance_update(balance) + balance + annual_yield(balance) + end + + def self.years_before_desired_balance(current_balance, desired_balance) + years = 0 + while current_balance < desired_balance + current_balance = annual_balance_update(current_balance) + years += 1 + end + years + end + + private + + def self.annual_yield(balance) + multiplier = interest_rate(balance) / 100 + balance.abs * multiplier + end +end diff --git a/exercises/concept/floating-point-numbers/savings_account.rb b/exercises/concept/floating-point-numbers/savings_account.rb new file mode 100644 index 0000000000..5979d9f202 --- /dev/null +++ b/exercises/concept/floating-point-numbers/savings_account.rb @@ -0,0 +1,13 @@ +module SavingsAccount + def self.interest_rate(balance) + raise NotImplementedError, 'Please implement the SavingsAccount.interest_rate method' + end + + def self.annual_balance_update(balance) + raise NotImplementedError, 'Please implement the SavingsAccount.annual_balance_update method' + end + + def self.years_before_desired_balance(current_balance, desired_balance) + raise NotImplementedError, 'Please implement the SavingsAccount.years_before_desired_balance method' + end +end diff --git a/exercises/concept/floating-point-numbers/savings_account_test.rb b/exercises/concept/floating-point-numbers/savings_account_test.rb new file mode 100644 index 0000000000..94ecd86d31 --- /dev/null +++ b/exercises/concept/floating-point-numbers/savings_account_test.rb @@ -0,0 +1,105 @@ +require 'minitest/autorun' +require_relative 'savings_account' + +class SavingsAccountTest < Minitest::Test + + def test_minimal_first_interest_rate + assert_equal 0.5, SavingsAccount.interest_rate(0) + end + + def test_tiny_first_interest_rate + assert_equal 0.5, SavingsAccount.interest_rate(0.000_001) + end + + def test_maximal_first_interest_rate + assert_equal 0.5, SavingsAccount.interest_rate(999.999) + end + + def test_minimal_second_interest_rate + assert_equal 1.621, SavingsAccount.interest_rate(1_000.0) + end + + def test_tiny_second_interest_rate + assert_equal 1.621, SavingsAccount.interest_rate(1_000.001) + end + + def test_maximal_second_interest_rate + assert_equal 1.621, SavingsAccount.interest_rate(4_999.999) + end + + def test_minimal_third_interest_rate + assert_equal 2.475, SavingsAccount.interest_rate(5_000.0) + end + + def test_tiny_third_interest_rate + assert_equal 2.475, SavingsAccount.interest_rate(5_000.001) + end + + def test_large_third_interest_rate + assert_equal 2.475, SavingsAccount.interest_rate(555_555_555.555) + end + + def test_minimal_negative_interest_rate + assert_equal -3.213, SavingsAccount.interest_rate(-0.0001) + end + + def test_small_negative_interest_rate + assert_equal -3.213, SavingsAccount.interest_rate(-0.123) + end + + def test_regular_negative_interest_rate + assert_equal -3.213, SavingsAccount.interest_rate(-300.0) + end + + def test_large_negative_interest_rate + assert_equal -3.213, SavingsAccount.interest_rate(-55_555.444) + end + + def test_annual_balance_update_for_empty_start_balance + assert_equal 0, SavingsAccount.annual_balance_update(0.0) + end + + def test_annual_balance_update_for_small_positive_start_balance + assert_equal 0.000_001_005, SavingsAccount.annual_balance_update(0.000_001) + end + + def test_annual_balance_update_for_avarage_positive_start_balance + assert_equal 1_016.21, SavingsAccount.annual_balance_update(1_000.0) + end + + def test_annual_balance_update_for_large_positive_start_balance + assert_equal 1_016.2_101_016_209_999, SavingsAccount.annual_balance_update(1_000.0001) + end + + def test_annual_balance_update_for_huge_positive_start_balance + assert_equal 920_352_587.26_744_292_868_451_875, SavingsAccount.annual_balance_update(898_124_017.826_243_404_425) + end + + def test_annual_balance_update_for_small_negative_start_balance + assert_equal -0.12_695_199, SavingsAccount.annual_balance_update(-0.123) + end + + def test_annual_balance_update_for_avarage_negative_start_balance + assert_equal 1_016.21, SavingsAccount.annual_balance_update(1_000.0) + end + + def test_annual_balance_update_for_large_negative_start_balance + assert_equal -157_878.97_174_203, SavingsAccount.annual_balance_update(-152_964.231) + end + + def test_years_before_desired_balance_for_small_start_balance + assert_equal 47, SavingsAccount.years_before_desired_balance(100.0, 125.8) + end + + def test_years_before_desired_balance_for_average_start_balance + assert_equal 6, SavingsAccount.years_before_desired_balance(1_000.0, 1_100.0) + end + + def test_years_before_desired_balance_for_large_start_balance + assert_equal 5, SavingsAccount.years_before_desired_balance(8_080.80, 9_090.9) + end + + def test_years_before_desired_balance_for_large_difference_between_start_and_desired_balance + assert_equal 85, SavingsAccount.years_before_desired_balance(2_345.67, 12_345.6_789) + end +end From b27be6b92a1da559e50eebfdad497c261cb30465 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 23 Apr 2020 17:01:49 +0200 Subject: [PATCH 017/102] Cross-reference concept exercise file information [Docs] Cross-reference concept exercise file information --- reference/implementing-a-concept-exercise.md | 25 ++++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/reference/implementing-a-concept-exercise.md b/reference/implementing-a-concept-exercise.md index 4252d9e98f..388775ef1d 100644 --- a/reference/implementing-a-concept-exercise.md +++ b/reference/implementing-a-concept-exercise.md @@ -16,7 +16,7 @@ As this document is generic, `` will be use as the placeholder for the nam Before implementing the exercise, please make sure you have a good understanding of what the exercise should be teaching (and what not). This information can be found in the exercise's GitHub issue. Having done this, please read the [Ruby concept exercises introduction][concept-exercises]. -To implement a concept exercise, the following files must be created: +To implement a concept exercise, the following files must be added:
 languages
@@ -28,8 +28,8 @@ languages
                 |   ├── instructions.md
                 |   ├── introduction.md
                 |   ├── hints.md
-                |   ├── source.md (required if there are third-party sources)
-                |   └── after.md
+                |   ├── after.md
+                |   └── source.md (required if there are third-party sources)
                 ├── .meta
                 |   |── config.json
                 |   |── design.md
@@ -38,29 +38,33 @@ languages
                 └── _test.rb
 
-## Step 1: adding track-specific files +## Step 1: Add code files -These files are specific to the Ruby track: +The code files are track-specific and should be designed to help the student learn the exercise's concepts. The following Ruby code files must be added (not necessarily in this order): - `.rb`. the stub implementation file, which is the starting point for students to work on the exercise. - `_test.rb`: the test suite. - `.meta/example.rb`: an example implementation that passes all the tests. -## Step 2: adding common files +## Step 2: Add documentation files How to create the files common to all tracks is described in the [how to implement a concept exercise document][how-to-implement-a-concept-exercise]. -## Step 3: add analyzer (optional) +## Step 3: Update list of implemented exercises + +- Add the exercise to the [list of implemented exercises][implemented-exercises]. + +## Step 4: Add analyzer (optional) Some exercises could benefit from having an exercise-specific [analyzer][analyzer]. If so, specify what analysis rules should be applied to this exercise and why. -Skip this step if you're not sure what to do. +_Skip this step if you're not sure what to do._ -## Step 4: custom representation (optional) +## Step 5: Add representation (optional) Some exercises could benefit from having an custom representation as generated by the [Ruby representer][representer]. If so, specify what changes to the representation should be applied and why. -Skip this step if you're not sure what to do. +_Skip this step if you're not sure what to do._ ## Inspiration @@ -80,3 +84,4 @@ If you have any questions regarding implementing the exercise, please post them [anatomy-of-a-concept-exercise]: https://www.youtube.com/watch?v=gkbBqd7hPrA [concept-exercise-strings]: ../exercises/concept/strings [reference]: ../../../reference +[implemented-exercises]: ../exercises/concept/README.md#implemented-exercises From 70ab75207d99b074ff33cec134a17f5e17dd7d4f Mon Sep 17 00:00:00 2001 From: Jeremy Walker Date: Wed, 6 May 2020 01:54:58 +0100 Subject: [PATCH 018/102] Remove constants from stub It seems that we accidentally leaked out constants into the stub. This removes them. --- exercises/concept/basics/lasagna.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/exercises/concept/basics/lasagna.rb b/exercises/concept/basics/lasagna.rb index ae6b9703c9..0e52a3a3f3 100644 --- a/exercises/concept/basics/lasagna.rb +++ b/exercises/concept/basics/lasagna.rb @@ -1,7 +1,4 @@ class Lasagna - EXPECTED_MINUTES_IN_OVEN = 40 - PREPARATION_MINUTES_PER_LAYER = 2 - def remaining_minutes_in_oven(actual_minutes_in_oven) raise NotImplementedError, 'Please implement the remaining_minutes_in_oven method' end From b5b654222f193527eef35bb950d0bf3ac0dbdcdf Mon Sep 17 00:00:00 2001 From: Viktor Date: Sat, 9 May 2020 17:03:58 +0200 Subject: [PATCH 019/102] New Concept exercise: numbers * Add ruby numbers concept exercise * Add floating-point-numbers to ruby lang config.json * Remove private keyword from example * Minor changes --- .../floating-point-numbers/.meta/example.rb | 2 - exercises/concept/numbers/.docs/after.md | 81 +++++++++++++++++++ exercises/concept/numbers/.docs/hints.md | 17 ++++ .../concept/numbers/.docs/instructions.md | 32 ++++++++ .../concept/numbers/.docs/introduction.md | 24 ++++++ exercises/concept/numbers/.meta/config.json | 9 +++ exercises/concept/numbers/.meta/design.md | 44 ++++++++++ exercises/concept/numbers/.meta/example.rb | 30 +++++++ exercises/concept/numbers/assembly_line.rb | 9 +++ .../concept/numbers/assembly_line_test.rb | 52 ++++++++++++ 10 files changed, 298 insertions(+), 2 deletions(-) create mode 100644 exercises/concept/numbers/.docs/after.md create mode 100644 exercises/concept/numbers/.docs/hints.md create mode 100644 exercises/concept/numbers/.docs/instructions.md create mode 100644 exercises/concept/numbers/.docs/introduction.md create mode 100644 exercises/concept/numbers/.meta/config.json create mode 100644 exercises/concept/numbers/.meta/design.md create mode 100644 exercises/concept/numbers/.meta/example.rb create mode 100644 exercises/concept/numbers/assembly_line.rb create mode 100644 exercises/concept/numbers/assembly_line_test.rb diff --git a/exercises/concept/floating-point-numbers/.meta/example.rb b/exercises/concept/floating-point-numbers/.meta/example.rb index 2a3c84876e..8ffc22bb95 100644 --- a/exercises/concept/floating-point-numbers/.meta/example.rb +++ b/exercises/concept/floating-point-numbers/.meta/example.rb @@ -30,8 +30,6 @@ def self.years_before_desired_balance(current_balance, desired_balance) years end - private - def self.annual_yield(balance) multiplier = interest_rate(balance) / 100 balance.abs * multiplier diff --git a/exercises/concept/numbers/.docs/after.md b/exercises/concept/numbers/.docs/after.md new file mode 100644 index 0000000000..9ad3149117 --- /dev/null +++ b/exercises/concept/numbers/.docs/after.md @@ -0,0 +1,81 @@ +One of the key aspects of working with numbers in Ruby is the distinction between integers (numbers with no digits after the decimal separator) and floating-point numbers (numbers with zero or more digits after the decimal separator). +They are implemented through the [`Integer`][integer-ruby] and [`Float`][float-ruby] class. + +```ruby +a = 1 +b = 1.0 +a.class +#=> Integer +b.class +#=> Float +``` + +- Arithmetic is done using the basic [arithmetic operators][arithmetic-operators] (`+`, `-`, `*`, `/`). Numbers can be compared using the standard [comparison operators][comparison-operators]. +- Basic arithmetic operations between instances of `Integer`, will always result in an instance of `Integer`. +- Basic arithmetic operations between instances of `Float` will result in other instances of `Float`. +- Basic arithmetic operations between instances of `Integer` and instances of `Float` will result in instances of `Float`. +- The `Float` and `Integer` classes have methods that will coerce values from one to the other. `Integer` numbers are precise to a whole unit, while `Float` has precision that is fractional to an whole number. This means that coercing a float to an integer may result in loss of precision. + +```ruby +4.9.to_i +#=> 4 + +5.to_f +#=> 5.0 + +7 - 3.0 +#=> 4.0 + +2 == 4 +#=> false + +1.0 == 1 +#=> true +``` + +An `if` statement can be used to conditionally execute code. The condition of an `if` statement does not have to be only `true` or `false`. It can be any value. But it's important to know that any value other than `nil` and `false` (_truthy_ values) will be treated as `true`, meaning that the code inside the `if` statement will be executed. + +```ruby +x = 5 + +if x == 5 + # Execute logic if x equals 5 +elsif x > 7 + # Execute logic if x greater than 7 +else + # Execute logic in all other cases +end +``` + +Sometimes you want to execute a statement (or statements) if a condition is _not_ true, for situations like that, Ruby implements the `unless` keyword: + +```ruby +x = 4 +unless x == 5 + # Execute logic if x does not equal 5 +else + # Execute logic if x == 5 +end +``` + +If you want to execute different code depending on the value of a variable, Ruby's `case` statement might come useful: + +```ruby +y = 5 +case y +when 3 + # Execute logic if y equals 3 +when 5 + # Execute logic if y equals 5 +else + # Execute logic in all other cases +end +``` + +The same problem can sometimes be solved using different types of conditional statements, sometimes one might be more suited for the problem than the other. It's a good idea to stop for a moment and also consider the other two options when using any of the three conditional statements. + +[arithmetic-operators]: https://www.tutorialspoint.com/ruby/ruby_operators.htm +[comparison-operators]: https://www.w3resource.com/ruby/ruby-comparison-operators.php +[if-else-unless]: https://www.w3resource.com/ruby/ruby-if-else-unless.php +[integer-ruby]: https://ruby-doc.org/core-2.7.1/Integer.html +[float-ruby]: https://ruby-doc.org/core-2.7.1/Float.html diff --git a/exercises/concept/numbers/.docs/hints.md b/exercises/concept/numbers/.docs/hints.md new file mode 100644 index 0000000000..06f191cb74 --- /dev/null +++ b/exercises/concept/numbers/.docs/hints.md @@ -0,0 +1,17 @@ +### General + +### 1. Calculate the production rate per second + +- Determining the success rate can be done through a [conditional statement][if-else-unless]. +- Multiplication can be done between instances of `Integer` and `Float`. The result will always be an instance of `Float`. +- Numbers can be compared using the built-in [comparison-operators][comparison-operators]. + +### 2. Calculate the number of working items produced per second + +- The `Float` class implements a [method][to_i] to return an instance of `Integer`. +- The `Integer` class implements a [method][to_f] to return an instance of `Float`. + +[comparison-operators]: https://www.w3resource.com/ruby/ruby-comparison-operators.php +[if-else-unless]: https://www.w3resource.com/ruby/ruby-if-else-unless.php +[to_f]: https://apidock.com/ruby/v2_6_3/Integer/to_f +[to_i]: https://apidock.com/ruby/Float/to_i diff --git a/exercises/concept/numbers/.docs/instructions.md b/exercises/concept/numbers/.docs/instructions.md new file mode 100644 index 0000000000..dd30574cca --- /dev/null +++ b/exercises/concept/numbers/.docs/instructions.md @@ -0,0 +1,32 @@ +In this exercise you'll be writing code to analyze the production of an assembly line in a car factory. The assembly line's speed can range from `0` (off) to `10` (maximum). + +At its slowest speed (`1`), `221` cars are produced each hour. The production increases linearly with the speed. So with the speed set to `4`, it should produce `4 * 221 = 884` cars per hour. However, higher speeds increase the likelihood that faulty cars are produced, which then have to be discarded. The following table shows how speed influences the success rate: + +- `1` to `4`: 100% success rate. +- `5` to `8`: 90% success rate. +- `9`: 80% success rate. +- `10`: 77% success rate. + +You have two tasks. + +### 1. Calculate the production rate per hour + +Implement the `AssemblyLine.production_rate_per_hour` method to calculate the assembly line's production rate per hour, taking into account its success rate: + +```ruby +AssemblyLine.production_rate_per_hour(6) +#=> 1193.4 +``` + +Note that the value returned is an instance of `Float`. + +### 2. Calculate the number of working items produced per minute + +Implement the `AssemblyLine.working_items_per_minute` method to calculate how many working cars are produced per minute: + +```ruby +AssemblyLine.working_items_per_minute(6) +#=> 19 +``` + +Note that the value returned is an instance of `Integer`. diff --git a/exercises/concept/numbers/.docs/introduction.md b/exercises/concept/numbers/.docs/introduction.md new file mode 100644 index 0000000000..eae5bb9f6b --- /dev/null +++ b/exercises/concept/numbers/.docs/introduction.md @@ -0,0 +1,24 @@ +Two common types of numbers in Ruby are: + +- Integers: numbers with no digits behind the decimal separator (whole numbers). Examples are `-6`, `0`, `1`, `25`, `976` and `500000`. +- Floating-point numbers: numbers with zero or more digits behind the decimal separator. Examples are `-2.4`, `0.1`, `3.14`, `16.984025` and `1024.0`. + +They are implemented through the `Integer` and `Float` classes. + +The `Float` and `Integer` classes have methods that will coerce values from one to the other. `Integer` numbers are precise to a whole unit, while `Float` has precision that is fractional to an whole number. + +In this exercise you must conditionally execute logic. A common way to do this in Ruby is by using an `if/else` statement: + +```ruby +x = 5 + +if x == 5 + # Execute logic if x equals 5 +elsif x > 7 + # Execute logic if x greater than 7 +else + # Execute logic in all other cases +end +``` + +The condition of an `if` statement does not have to be only `true` or `false`. It can be any value. But it's important to know that any value other than `nil` and `false` (_truthy_ values) will be treated as `true`, meaning that the code inside the `if` statement will be executed. diff --git a/exercises/concept/numbers/.meta/config.json b/exercises/concept/numbers/.meta/config.json new file mode 100644 index 0000000000..5433c10617 --- /dev/null +++ b/exercises/concept/numbers/.meta/config.json @@ -0,0 +1,9 @@ +{ + "authors": [ + { + "github_username": "dvik1950", + "exercism_username": "dvik1950" + } + ], + "forked_from": ["csharp/numbers"] +} diff --git a/exercises/concept/numbers/.meta/design.md b/exercises/concept/numbers/.meta/design.md new file mode 100644 index 0000000000..00cfa3391c --- /dev/null +++ b/exercises/concept/numbers/.meta/design.md @@ -0,0 +1,44 @@ +# Design + +## Goal + +The goal of this exercise is to teach the student how the concept of numbers is implemented in Ruby. It will introduce this concept through the two most common numeric types in Ruby: [`Integer`][integer-ruby] (whole number) and [`Float`][float-ruby] (floating-point number). + +## Learning objectives + +- Know of the existence of `Integer` and `Float`. +- Understand that an `Integer` represents whole numbers, and a `Float` represents floating-point numbers. +- Know of basic operators such as multiplication, comparison and equality. +- Know how to conditionally execute code using an `if`, `unless` or `case` statement. + +## Out of scope + +- Any other numeric types besides `Integer` and `Float` (so no `Rational`, `Complex`, `BigDecimal`, etc.). +- Parsing an instance of `String` to an instance of `Integer` or `Float`. +- Coercing an instance of `Integer` or `Float` to an instance of `String`. + +## Concepts + +The Concepts this exercise unlocks are: + +- `numbers`: know of the existence of the two commonly used number types, `Integer` and `Float`; understand that the former represents whole numbers, and the latter floating-point numbers; know of basic operators such as multiplication, comparison and equality; know how to coerce one numeric type to another +- `conditionals`: know how to conditionally execute code using an `if`, `unless` or `case` statement. + +## Prerequisites + +This exercise's prerequisite Concepts are: + +- `basics`: know how to define methods. + +## Representer + +This exercise does not require any specific representation logic to be added to the [representer][representer]. + +## Analyzer + +This exercise does not require any specific logic to be added to the [analyzer][analyzer]. + +[integer-ruby]: https://ruby-doc.org/core-2.7.1/Integer.html +[float-ruby]: https://ruby-doc.org/core-2.7.1/Float.html +[analyzer]: https://github.com/exercism/ruby-analyzer +[representer]: https://github.com/exercism/ruby-representer diff --git a/exercises/concept/numbers/.meta/example.rb b/exercises/concept/numbers/.meta/example.rb new file mode 100644 index 0000000000..06752516b7 --- /dev/null +++ b/exercises/concept/numbers/.meta/example.rb @@ -0,0 +1,30 @@ +class AssemblyLine + + CARS_PER_HOUR = 221 + MINUTES_IN_HOUR = 60 + # Success rates + ONE_TO_FOUR_RATE = 1.00 + FIVE_TO_EIGHT_RATE = 0.90 + NINE_RATE = 0.80 + TEN_RATE = 0.77 + + def self.production_rate_per_hour(speed) + CARS_PER_HOUR * speed * success_rate(speed) + end + + def self.working_items_per_minute(speed) + (production_rate_per_hour(speed) / MINUTES_IN_HOUR).to_i + end + + def self.success_rate(speed) + if speed <= 4 + ONE_TO_FOUR_RATE + elsif speed <= 8 + FIVE_TO_EIGHT_RATE + elsif speed <= 9 + NINE_RATE + else + TEN_RATE + end + end +end diff --git a/exercises/concept/numbers/assembly_line.rb b/exercises/concept/numbers/assembly_line.rb new file mode 100644 index 0000000000..08e2a147bb --- /dev/null +++ b/exercises/concept/numbers/assembly_line.rb @@ -0,0 +1,9 @@ +class AssemblyLine + def self.production_rate_per_hour(speed) + raise NotImplementedError, 'Please implement the AssemblyLine.production_rate_per_hour method' + end + + def self.working_items_per_minute(speed) + raise NotImplementedError, 'Please implement the AssemblyLine.working_items_per_minute method' + end +end diff --git a/exercises/concept/numbers/assembly_line_test.rb b/exercises/concept/numbers/assembly_line_test.rb new file mode 100644 index 0000000000..a4e80a49c4 --- /dev/null +++ b/exercises/concept/numbers/assembly_line_test.rb @@ -0,0 +1,52 @@ +require 'minitest/autorun' +require_relative 'assembly_line' + +class AssemblyLineTest < Minitest::Test + def test_production_rate_per_hour_for_speed_zero + assert_equal 0.0, AssemblyLine.production_rate_per_hour(0) + end + + def test_production_rate_per_hour_for_speed_one + assert_equal 221.0, AssemblyLine.production_rate_per_hour(1) + end + + def test_production_rate_per_hour_for_speed_four + assert_equal 884.0, AssemblyLine.production_rate_per_hour(4) + end + + def test_production_rate_per_hour_for_speed_seven + assert_equal 1392.3, AssemblyLine.production_rate_per_hour(7) + end + + def test_production_rate_per_hour_for_speed_nine + assert_equal 1591.2, AssemblyLine.production_rate_per_hour(9) + end + + def test_production_rate_per_hour_for_speed_ten + assert_equal 1701.7, AssemblyLine.production_rate_per_hour(10) + end + + def test_working_items_per_minute_for_speed_zero + assert_equal 0, AssemblyLine.working_items_per_minute(0) + end + + def test_working_items_per_minute_for_speed_one + assert_equal 3, AssemblyLine.working_items_per_minute(1) + end + + def test_working_items_per_minute_for_speed_five + assert_equal 16, AssemblyLine.working_items_per_minute(5) + end + + def test_working_items_per_minute_for_speed_eight + assert_equal 26, AssemblyLine.working_items_per_minute(8) + end + + def test_working_items_per_minute_for_speed_nine + assert_equal 26, AssemblyLine.working_items_per_minute(9) + end + + def test_working_items_per_minute_for_speed_ten + assert_equal 28, AssemblyLine.working_items_per_minute(10) + end +end From 695ab0eed8d01af2e9a1052349bd73c3bf1ce574 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 22 May 2020 16:21:59 +0200 Subject: [PATCH 020/102] Use consistent headings in documentation --- exercises/concept/basics/.docs/hints.md | 8 ++++---- exercises/concept/basics/.docs/instructions.md | 8 ++++---- exercises/concept/floating-point-numbers/.docs/hints.md | 8 ++++---- .../concept/floating-point-numbers/.docs/instructions.md | 6 +++--- exercises/concept/numbers/.docs/hints.md | 6 +++--- exercises/concept/numbers/.docs/instructions.md | 4 ++-- exercises/concept/strings/.docs/hints.md | 8 ++++---- exercises/concept/strings/.docs/instructions.md | 6 +++--- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/exercises/concept/basics/.docs/hints.md b/exercises/concept/basics/.docs/hints.md index 69af121c25..aa6d55dd2f 100644 --- a/exercises/concept/basics/.docs/hints.md +++ b/exercises/concept/basics/.docs/hints.md @@ -1,21 +1,21 @@ -### 1. Define the expected oven time in minutes +## 1. Define the expected oven time in minutes - You need to define a [constant][constant] which should contain the [integer][integers] value specified in the recipe. -### 2. Calculate the remaining oven time in minutes +## 2. Calculate the remaining oven time in minutes - You need to define a [method][methods] with a single parameter for the actual time so far. - You can [implicitly return an integer][return] from the method. - You can use the [mathematical operator for subtraction][operators] to subtract values. -### 3. Calculate the preparation time in minutes +## 3. Calculate the preparation time in minutes - You need to define a [method][methods] with a single parameter for the number of layers. - You can [implicitly return an integer][return] from the method. - You can use the [mathematical operator for multiplicaton][operators] to multiply values. - You could define an extra constant for the time in minutes per layer, or use a "magic number" in the code. -### 4. Calculate the total working time in minutes +## 4. Calculate the total working time in minutes - You need to define a [method][methods] with two named parameters: `number_of_layers` and `actual_minutes_in_oven`. - You can [implicitly return an integer][return] from the method. diff --git a/exercises/concept/basics/.docs/instructions.md b/exercises/concept/basics/.docs/instructions.md index 01345990ff..c8ac1801e9 100644 --- a/exercises/concept/basics/.docs/instructions.md +++ b/exercises/concept/basics/.docs/instructions.md @@ -2,7 +2,7 @@ In this exercise you're going to write some code to help you cook a brilliant la You have four tasks, all related to the time spent cooking the lasagna. -### 1. Define the expected oven time in minutes +## 1. Define the expected oven time in minutes Define the `Lasagna::EXPECTED_MINUTES_IN_OVEN` constant that returns how many minutes the lasagna should be in the oven. According to the cooking book, the expected oven time in minutes is 40: @@ -11,7 +11,7 @@ Lasagna::EXPECTED_MINUTES_IN_OVEN # => 40 ``` -### 2. Calculate the remaining oven time in minutes +## 2. Calculate the remaining oven time in minutes Define the `Lasagna#remaining_minutes_in_oven` method 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. @@ -21,7 +21,7 @@ lasagna.remaining_minutes_in_oven(30) # => 10 ``` -### 3. Calculate the preparation time in minutes +## 3. Calculate the preparation time in minutes Define the `Lasagna#preparation_time_in_minutes` method 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. @@ -31,7 +31,7 @@ lasagna.preparation_time_in_minutes(2) # => 4 ``` -### 4. Calculate the total working time in minutes +## 4. Calculate the total working time in minutes Define the `Lasagna#total_time_in_minutes` method that takes two named parameters: the `number_of_layers` parameter is the number of layers you added to the lasagna, and the `actual_minutes_in_oven` 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. diff --git a/exercises/concept/floating-point-numbers/.docs/hints.md b/exercises/concept/floating-point-numbers/.docs/hints.md index b733bcec70..48fe320a80 100644 --- a/exercises/concept/floating-point-numbers/.docs/hints.md +++ b/exercises/concept/floating-point-numbers/.docs/hints.md @@ -1,13 +1,13 @@ -### General +## General -### 1. Calculate the interest rate +## 1. Calculate the interest rate - Using an `if` or `case` statement can be useful when checking conditions. -### 2. Calculate the annual balance update +## 2. Calculate the annual balance update - When calculating the annual yield, it might be useful to temporarily convert a negative balance to a positive one. The `Float` class has a method to convert both positive and negative values to their absolute value. -### 3. Calculate the years before reaching the desired balance +## 3. Calculate the years before reaching the desired balance - To calculate the years, one can keep looping until the desired balance is reached. diff --git a/exercises/concept/floating-point-numbers/.docs/instructions.md b/exercises/concept/floating-point-numbers/.docs/instructions.md index 11a49a9d19..ed013ef5d9 100644 --- a/exercises/concept/floating-point-numbers/.docs/instructions.md +++ b/exercises/concept/floating-point-numbers/.docs/instructions.md @@ -7,7 +7,7 @@ In this exercise you'll be working with savings accounts. Each year, the balance You have three tasks, each of which will deal the balance and its interest rate. -### 1. Calculate the interest rate +## 1. Calculate the interest rate Implement the `SavingsAccount.interest_rate` method to calculate the interest rate based on the specified balance: @@ -18,7 +18,7 @@ SavingsAccount.interest_rate(200.75) Note that the value returned is an instance of `Float`. -### 2. Calculate the annual balance update +## 2. Calculate the annual balance update Implement the `SavingsAccount.annual_balance_update` method to calculate the annual balance update, taking into account the interest rate: @@ -29,7 +29,7 @@ SavingsAccount.annual_balance_update(200.75) Note that the value returned is an instance of `Float`. -### 3. Calculate the years before reaching the desired balance +## 3. Calculate the years before reaching the desired balance Implement the `SavingsAccount.years_before_desired_balance` method to calculate the minimum number of years required to reach the desired balance: diff --git a/exercises/concept/numbers/.docs/hints.md b/exercises/concept/numbers/.docs/hints.md index 06f191cb74..f84ce5fcb7 100644 --- a/exercises/concept/numbers/.docs/hints.md +++ b/exercises/concept/numbers/.docs/hints.md @@ -1,12 +1,12 @@ -### General +## General -### 1. Calculate the production rate per second +## 1. Calculate the production rate per second - Determining the success rate can be done through a [conditional statement][if-else-unless]. - Multiplication can be done between instances of `Integer` and `Float`. The result will always be an instance of `Float`. - Numbers can be compared using the built-in [comparison-operators][comparison-operators]. -### 2. Calculate the number of working items produced per second +## 2. Calculate the number of working items produced per second - The `Float` class implements a [method][to_i] to return an instance of `Integer`. - The `Integer` class implements a [method][to_f] to return an instance of `Float`. diff --git a/exercises/concept/numbers/.docs/instructions.md b/exercises/concept/numbers/.docs/instructions.md index dd30574cca..315dcc571f 100644 --- a/exercises/concept/numbers/.docs/instructions.md +++ b/exercises/concept/numbers/.docs/instructions.md @@ -9,7 +9,7 @@ At its slowest speed (`1`), `221` cars are produced each hour. The production in You have two tasks. -### 1. Calculate the production rate per hour +## 1. Calculate the production rate per hour Implement the `AssemblyLine.production_rate_per_hour` method to calculate the assembly line's production rate per hour, taking into account its success rate: @@ -20,7 +20,7 @@ AssemblyLine.production_rate_per_hour(6) Note that the value returned is an instance of `Float`. -### 2. Calculate the number of working items produced per minute +## 2. Calculate the number of working items produced per minute Implement the `AssemblyLine.working_items_per_minute` method to calculate how many working cars are produced per minute: diff --git a/exercises/concept/strings/.docs/hints.md b/exercises/concept/strings/.docs/hints.md index d890de9b9e..66d46458fd 100644 --- a/exercises/concept/strings/.docs/hints.md +++ b/exercises/concept/strings/.docs/hints.md @@ -1,18 +1,18 @@ -### General +## General - The [rubymostas strings guide][ruby-for-beginners.rubymonstas.org-strings] has a nice introduction to Ruby strings. - The `String` object has many useful [built-in methods][docs-string-methods]. -### 1. Get message from a log line +## 1. Get message from a log line - There are different ways to search for text in a string, which can be found on the [Ruby language official documentation][docs-string-methods]. - There are [built in methods][strip-white-space] to strip white space. -### 2. Get log level from a log line +## 2. Get log level from a log line - Ruby `String` objects have a [method][downcase] to perform this operation. -### 3. Reformat a log line +## 3. Reformat a log line - There are several ways to [concatenate strings][ruby-for-beginners.rubymonstas.org-strings], but the preferred one is usually [string interpolation][ruby-for-beginners.rubymonstas.org-strings] diff --git a/exercises/concept/strings/.docs/instructions.md b/exercises/concept/strings/.docs/instructions.md index bb4c59fde4..e8f6d0e01a 100644 --- a/exercises/concept/strings/.docs/instructions.md +++ b/exercises/concept/strings/.docs/instructions.md @@ -10,7 +10,7 @@ There are three different log levels: You have three tasks, each of which will take a log line and ask you to do something with it. -### 1. Get message from a log line +## 1. Get message from a log line Implement a method to return a log line's message: @@ -26,7 +26,7 @@ LogLineParser.message('[WARNING]: Disk almost full\r\n') // Returns: "Disk almost full" ``` -### 2. Get log level from a log line +## 2. Get log level from a log line Implement a method to return a log line's log level, which should be returned in lowercase: @@ -35,7 +35,7 @@ LogLineParser.log_level('[ERROR]: Invalid operation') // Returns: "error" ``` -### 3. Reformat a log line +## 3. Reformat a log line Implement a method that reformats the log line, putting the message first and the log level after it in parentheses: From 544745d034c45862d73959be63667565ca3b0723 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 May 2020 11:23:28 +0200 Subject: [PATCH 021/102] Remove top-level header from design.md files --- exercises/concept/basics/.meta/design.md | 2 -- exercises/concept/floating-point-numbers/.meta/design.md | 2 -- exercises/concept/numbers/.meta/design.md | 2 -- exercises/concept/strings/.meta/design.md | 2 -- 4 files changed, 8 deletions(-) diff --git a/exercises/concept/basics/.meta/design.md b/exercises/concept/basics/.meta/design.md index d566426ae6..27e6db0f8e 100644 --- a/exercises/concept/basics/.meta/design.md +++ b/exercises/concept/basics/.meta/design.md @@ -1,5 +1,3 @@ -# Design - ## Goal The goal of this exercise is to teach the student the basics of programming in Ruby. diff --git a/exercises/concept/floating-point-numbers/.meta/design.md b/exercises/concept/floating-point-numbers/.meta/design.md index 0d28f2a147..a0dac57c18 100644 --- a/exercises/concept/floating-point-numbers/.meta/design.md +++ b/exercises/concept/floating-point-numbers/.meta/design.md @@ -1,5 +1,3 @@ -# Design - ## Goal The goal of this exercise is to teach the student the concept of floating-point numbers and introduce them to loops. diff --git a/exercises/concept/numbers/.meta/design.md b/exercises/concept/numbers/.meta/design.md index 00cfa3391c..f247e44495 100644 --- a/exercises/concept/numbers/.meta/design.md +++ b/exercises/concept/numbers/.meta/design.md @@ -1,5 +1,3 @@ -# Design - ## Goal The goal of this exercise is to teach the student how the concept of numbers is implemented in Ruby. It will introduce this concept through the two most common numeric types in Ruby: [`Integer`][integer-ruby] (whole number) and [`Float`][float-ruby] (floating-point number). diff --git a/exercises/concept/strings/.meta/design.md b/exercises/concept/strings/.meta/design.md index 4c5bd05a82..406f5b9d03 100644 --- a/exercises/concept/strings/.meta/design.md +++ b/exercises/concept/strings/.meta/design.md @@ -1,5 +1,3 @@ -# Design - ## Goal The goal of this exercise is to teach the student the basics of the Concept of Strings in [Ruby][ruby-doc.org-string]. From 5b7c183f1c1e7e619e46dda538b926f5ecbf4771 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Tue, 16 Jun 2020 07:35:13 +0200 Subject: [PATCH 022/102] Concept Exercise: arrays * Concept Exercise: arrays --- exercises/concept/arrays/.docs/after.md | 54 ++++++++++++ exercises/concept/arrays/.docs/hints.md | 35 ++++++++ .../concept/arrays/.docs/instructions.md | 57 +++++++++++++ .../concept/arrays/.docs/introduction.md | 84 +++++++++++++++++++ exercises/concept/arrays/.meta/config.json | 9 ++ exercises/concept/arrays/.meta/design.md | 52 ++++++++++++ exercises/concept/arrays/.meta/example.rb | 26 ++++++ exercises/concept/arrays/bird_count.rb | 26 ++++++ exercises/concept/arrays/bird_count_test.rb | 67 +++++++++++++++ 9 files changed, 410 insertions(+) create mode 100644 exercises/concept/arrays/.docs/after.md create mode 100644 exercises/concept/arrays/.docs/hints.md create mode 100644 exercises/concept/arrays/.docs/instructions.md create mode 100644 exercises/concept/arrays/.docs/introduction.md create mode 100644 exercises/concept/arrays/.meta/config.json create mode 100644 exercises/concept/arrays/.meta/design.md create mode 100644 exercises/concept/arrays/.meta/example.rb create mode 100644 exercises/concept/arrays/bird_count.rb create mode 100644 exercises/concept/arrays/bird_count_test.rb diff --git a/exercises/concept/arrays/.docs/after.md b/exercises/concept/arrays/.docs/after.md new file mode 100644 index 0000000000..3d78c7a5c5 --- /dev/null +++ b/exercises/concept/arrays/.docs/after.md @@ -0,0 +1,54 @@ +Data structures that can hold zero or more elements are known as _collections_. An **array** in Ruby is a collection that maintains the ordering in which its objects are added. Arrays can hold any object. Objects can be added to an array or retrieved from it using an index. Ruby array indexing is zero-based, meaning that the first element's index is always zero: + +```ruby +# Declare an array containing two values +two_ints = [1,2]; + +# Assign first and second element by index +two_ints[0] = 7; +two_ints[1] = 8; + +# Retrieve the second element by index +two_ints[1] # => 8 + +# Check the length of the array +two_ints.size # => 2 +``` + +In Ruby there are multiple ways of creating an Array: + +- Using the literal constructor `[]` _(most common)_ +- Explicitly calling `Array.new` +- Calling the Kernel `Array()` method + +The `Array.new` method supports two optional arguments: the initial size of the array and a default object. + +When a size and default are provided, the array is populated with `size` copies of default object. + +```ruby +a = Array.new(2, Hash.new) +# => [{}, {}] +``` + +Since all the Array elements store the same hash, changes to one of them will affect them all. + +```ruby +a[0]['cat'] = 'feline' +a # => [{"cat"=>"feline"}, {"cat"=>"feline"}] + +a[1]['cat'] = 'Felix' +a # => [{"cat"=>"Felix"}, {"cat"=>"Felix"}] +``` + +If multiple copies are what you want, you should use the block version which uses the result of that block each time an element of the array needs to be initialized: + +```ruby +a = Array.new(2) {Hash.new} +a[0]['cat'] = 'feline' +a # => [{"cat"=>"feline"}, {}] +``` + +Another characteristic of Ruby arrays is that they mix in the [Enumerable][enumerable-module] module, which adds a lot of handy methods to iterate, search, sort, filter, etc. elements of an array. + +[enumerable-module]: https://ruby-doc.org/core-2.7.1/Enumerable.html +[for-loop]: https://launchschool.com/books/ruby/read/loops_iterators#forloops diff --git a/exercises/concept/arrays/.docs/hints.md b/exercises/concept/arrays/.docs/hints.md new file mode 100644 index 0000000000..0fdabafeee --- /dev/null +++ b/exercises/concept/arrays/.docs/hints.md @@ -0,0 +1,35 @@ +### General + +- The bird count per day is stored in a [instance variable][instace-variable] named `birds_per_day`. +- The bird count per day is an array that contains exactly 7 integers. + +### 1. Check what the counts were last week + +- As this method does _not_ depend on the current week's count, it is defined as a [`class` method][class-method]. +- There are [several ways to define an array][array-definition]. + +### 2. Check how many birds visited yesterday + +- Remember that the counts are ordered by day from oldest to most recent, with the last element representing today. +- Accessing the second last element can be done either by using its (fixed) index (remember to start counting from zero) or by calculating its index using the [array's size][array-length]. + +### 3. Calculate the total number of visiting birds + +- It's possible to calculate the sum of a collection using the [Array#sum][array-sum] method. + +### 4. Calculate the number of busy days + +- Ruby also provides a method for [counting elements on a collection][array-count] + +### 5. Check if there was a day with no visiting birds + +- There are some methods that can be use to check the existence on an element on a colection. For example [Enumerable#any?][enumerable-any] and [Enumerable#all?][enumerable-all] + +[instance-variables]: http://ruby-for-beginners.rubymonstas.org/writing_classes/instance_variables.html +[class-method]: http://www.rubyfleebie.com/2007/04/09/understanding-class-methods-in-ruby/ +[array-definition]: https://ruby-doc.org/core-2.7.0/Array.html#class-Array-label-Creating+Arrays +[array-length]: https://ruby-doc.org/core-2.7.0/Array.html#class-Array-label-Obtaining+Information+about+an+Array +[array-sum]: https://ruby-doc.org/core-2.7.0/Array.html#method-i-sum +[array-count]: https://ruby-doc.org/core-2.7.0/Array.html#method-i-count +[enumerable-any]: https://ruby-doc.org/core-2.7.0/Enumerable.html#method-i-any-3F +[enumerable-all]: https://ruby-doc.org/core-2.7.0/Enumerable.html#method-i-all-3F diff --git a/exercises/concept/arrays/.docs/instructions.md b/exercises/concept/arrays/.docs/instructions.md new file mode 100644 index 0000000000..859f8a1dcc --- /dev/null +++ b/exercises/concept/arrays/.docs/instructions.md @@ -0,0 +1,57 @@ +You're an avid bird watcher that keeps track of how many birds have visited your garden in the last seven days. + +You have five tasks, all dealing with the numbers of birds that visited your garden. + +### 1. Check what the counts were last week + +For comparison purposes, you always keep a copy of last week's counts nearby, which were: 0, 2, 5, 3, 7, 8 and 4. Implement the `BirdCount.last_week` method that returns last week's counts: + +```ruby +BirdCount.last_week +# => [0, 2, 5, 3, 7, 8, 4] +``` + +### 2. Check how many birds visited yesterday + +Implement the `BirdCount#yesterday` method to return how many birds visited your garden yesterday. The bird counts are ordered by day, with the first element being the count of the oldest day, and the last element being today's count. + +```ruby +birds_per_day = [2, 5, 0, 7, 4, 1] +bird_count = new BirdCount(birds_per_day) +bird_count.yesterday +# => 4 +``` + +### 3. Calculate the total number of visiting birds + +Implement the `BirdCount#total` method to return the total number of birds that have visited your garden: + +```ruby +birds_per_day = [2, 5, 0, 7, 4, 1] +bird_count = new BirdCount(birds_per_day) +bird_count.total +# => 19 +``` + +### 4. Calculate the number of busy days + +Some days are busier that others. A busy day is one where five or more birds have visited your garden. +Implement the `BirdCount#busy_days` method to return the number of busy days: + +```ruby +birds_per_day = [2, 5, 0, 7, 4, 1] +bird_count = new BirdCount(birds_per_day) +bird_count.busy_days +# => 2 +``` + +### 5. Check if there was a day with no visiting birds + +Implement the `BirdCount#day_without_birds?` method that returns `true` if there was a day at which zero birds visited the garden; otherwise, return `false`: + +```ruby +birds_per_day = [2, 5, 0, 7, 4, 1] +ird_count = new BirdCount(birds_per_day) +bird_count.day_without_birds? +# => true +``` diff --git a/exercises/concept/arrays/.docs/introduction.md b/exercises/concept/arrays/.docs/introduction.md new file mode 100644 index 0000000000..ac17cb6f6b --- /dev/null +++ b/exercises/concept/arrays/.docs/introduction.md @@ -0,0 +1,84 @@ +In Ruby, **arrays** are ordered, integer-indexed collections of any object. Array indexing starts at `0`. A negative index is assumed to be relative to the end of the array — i.e. an index of `-1` indicates the last element of the array, `-2` is the next to last element in the array, and so on. +Ruby arrays mix in the [Enumerable module][enumerable-module], which adds several traversal and searching methods, and with the ability to sort. + +### Create array. + +- An array in Ruby can contain different types of objects. + +```ruby +array = [1, "two", 3.0] #=> [1, "two", 3.0] +``` + +### Element Assignment + +Elements can accessed or changed using indexes. Subarrays can be accessed by specifying a start index and a size. + +```ruby +a = ["", "", "", "", ""] + +a[4] = "hello" #=> [nil, nil, nil, nil, "hello"] +a[0, 3] = [ 'a', 'b', 'c' ] #=> ["a", "b", "c", nil, "hello"] +``` + +- Negative indices will count backward from the end of the array. + +```ruby +a = ['a', 'b'] + +a[-1] = "Z" +a #=> ["a", "Z"] +``` + +### Element Reference + +- Elements in an array can be retrieved using the #[] method. It returns the element at index, or returns a subarray starting at the start index and continuing for length elements. + +```ruby +a = [ "a", "b", "c", "d", "e" ] + +a[2] #=> "c" +a[6] #=> nil +a[1, 2] #=> [ "b", "c" ] +``` + +- Negative indices count backward from the end of the array (-1 is the last element) + +```ruby +a = [ "a", "b", "c", "d", "e" ] + +a[-2] #=> "d" +a[-3, 3] #=> [ "c", "d", "e" ] +``` + +### Obtaining Information about an Array + +Arrays keep track of their own length at all times. To query an array about the number of elements it contains, use length, count or size. + +```ruby +browsers = ['Chrome', 'Firefox', 'Safari', 'Opera', 'IE'] +browsers.length #=> 5 +browsers.count #=> 5 +browsers.size #=> 5 +``` + +### Adding Items to Arrays + +Items can be added to the end of an array by using either push or << + +```ruby +arr = [1, 2, 3, 4] +arr.push(5) #=> [1, 2, 3, 4, 5] +arr << 6 #=> [1, 2, 3, 4, 5, 6] +``` + +### Removing Items from an Array + +The method pop removes the last element in an array and returns it + +```ruby +arr = [1, 2, 3, 4, 5, 6] +arr.pop #=> 6 +arr #=> [1, 2, 3, 4, 5] +``` + +[enumerable-module]: https://ruby-doc.org/core-2.7.1/Enumerable.html diff --git a/exercises/concept/arrays/.meta/config.json b/exercises/concept/arrays/.meta/config.json new file mode 100644 index 0000000000..827e937cbe --- /dev/null +++ b/exercises/concept/arrays/.meta/config.json @@ -0,0 +1,9 @@ +{ + "authors": [ + { + "github_username": "pvcarrera", + "exercism_username": "pvcarrera" + } + ], + "forked_from": ["csharp/arrays"] +} diff --git a/exercises/concept/arrays/.meta/design.md b/exercises/concept/arrays/.meta/design.md new file mode 100644 index 0000000000..967ba999f9 --- /dev/null +++ b/exercises/concept/arrays/.meta/design.md @@ -0,0 +1,52 @@ +# Design + +## Goal + +The goal of this exercise is to teach the student the basics of the Concept of Arrays in Ruby. + +Of the many available Ruby collections, we chose to use the `array` collection type as the first collection type students will be taught for the following reasons: + +- Arrays are a common data type in many languages. +- Arrays have a fixed length. No complexity in adding or removing elements. +- Arrays have a simple shorthand syntax. No need to understand how initializers work to define an array. + +## Learning objectives + +- The existence of the `Array` object. +- Defining an array. +- Accessing elements in an array by index. +- Iterating over elements in an array. +- Basic array methods (like size or sum). + +## Out of scope + +- Multi-dimensional/jagged arrays. +- Memory and performance characteristics of arrays. +- Iterators. + +## Concepts + +This Concepts Exercise's Concepts are: + +- `arrays`: know of the existence of the `Array` object; know how to define an array; know how to access elements in an array by index; know how to iterate over elements in an array; know of some basic functions. +- `each loops`: know how to iterate over a collection. + +## Prequisites + +This exercise's prerequisites Concepts are: + +- `classes`: know how to work with instance variables. +- `for-loops`: know what a `for` loop is. +- `booleans`: know what a `boolean` is. +- `basics`: know how to assign and update variables. + +## Representer + +This exercise does not require any specific representation logic to be added to the [representer][representer]. + +## Analyzer + +This exercise does not require any specific logic to be added to the [analyzer][analyzer]. + +[analyzer]: https://github.com/exercism/ruby-analyzer +[representer]: https://github.com/exercism/ruby-representer diff --git a/exercises/concept/arrays/.meta/example.rb b/exercises/concept/arrays/.meta/example.rb new file mode 100644 index 0000000000..401eda615b --- /dev/null +++ b/exercises/concept/arrays/.meta/example.rb @@ -0,0 +1,26 @@ +class BirdCount + def self.last_week + [0, 2, 5, 3, 7, 8, 4] + end + + def initialize(birds_per_day) + @birds_per_day = birds_per_day + end + + def yesterday + @birds_per_day[5] + end + + def total + @birds_per_day.sum + end + + def busy_days + @birds_per_day.count { |birds| birds >= 5 } + end + + def day_without_birds? + @birds_per_day.any? { |birds| birds == 0 } + end +end + diff --git a/exercises/concept/arrays/bird_count.rb b/exercises/concept/arrays/bird_count.rb new file mode 100644 index 0000000000..91827423b1 --- /dev/null +++ b/exercises/concept/arrays/bird_count.rb @@ -0,0 +1,26 @@ +class BirdCount + def self.lastWeek + raise NotImplementedError, 'Please implement the BirdCount.lastWeek method' + end + + def initialize(birds_per_day) + raise NotImplementedError, 'Please implement the BirdCount#initialize method' + end + + def yesterday + raise NotImplementedError, 'Please implement the BirdCount#yesterday method' + end + + def total + raise NotImplementedError, 'Please implement the BirdCount#total method' + end + + def busy_days + raise NotImplementedError, 'Please implement the BirdCount#busy_days method' + end + + def day_without_birds? + raise NotImplementedError, 'Please implement the BirdCount#day_without_birds method' + end +end + diff --git a/exercises/concept/arrays/bird_count_test.rb b/exercises/concept/arrays/bird_count_test.rb new file mode 100644 index 0000000000..e52e554604 --- /dev/null +++ b/exercises/concept/arrays/bird_count_test.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require 'minitest/autorun' +require_relative 'bird_count' + +class LasagnaTest < Minitest::Test + def test_last_week + assert_equal [0, 2, 5, 3, 7, 8, 4], BirdCount.last_week + end + + def test_yesterday_for_dissapointing_week + counts = [0, 0, 1, 0, 0, 1, 0] + bird_count = BirdCount.new(counts) + + assert_equal 1, bird_count.yesterday + end + + def test_yesterday_for_busy_week + counts = [8, 8, 9, 5, 4, 7, 10] + bird_count = BirdCount.new(counts) + + assert_equal 7, bird_count.yesterday + end + + def test_total_for_dissapointing_week + counts = [0, 0, 1, 0, 0, 1, 0] + bird_count = BirdCount.new(counts) + + assert_equal 2, bird_count.total + end + + def test_total_for_busy_week + counts = [5, 9, 12, 6, 8, 8, 17] + bird_count = BirdCount.new(counts) + + assert_equal 65, bird_count.total + end + + def test_busy_days_for_dissapointing_week + counts = [1, 1, 1, 0, 0, 0, 0] + bird_count = BirdCount.new(counts) + + assert_equal 0, bird_count.busy_days + end + + def test_busy_days_for_busy_week + counts = [4, 9, 5, 7, 8, 8, 2] + bird_count = BirdCount.new(counts) + + assert_equal 5, bird_count.busy_days + end + + def test_has_day_without_birds + counts = [5, 5, 4, 0, 7, 6] + bird_count = BirdCount.new(counts) + + assert bird_count.day_without_birds? + end + + def test_has_day_without_birds_whith_no_day_without_birds + counts = [4, 5, 9, 10, 9, 4, 3] + bird_count = BirdCount.new(counts) + + refute bird_count.day_without_birds? + end +end + From 1f1601429aa3ed345995907154467cf80f003e7f Mon Sep 17 00:00:00 2001 From: Oana Date: Sun, 5 Jul 2020 15:40:46 +0100 Subject: [PATCH 023/102] Fix typo in function name --- exercises/concept/basics/lasagna.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/concept/basics/lasagna.rb b/exercises/concept/basics/lasagna.rb index 0e52a3a3f3..17e61dea0a 100644 --- a/exercises/concept/basics/lasagna.rb +++ b/exercises/concept/basics/lasagna.rb @@ -3,8 +3,8 @@ def remaining_minutes_in_oven(actual_minutes_in_oven) raise NotImplementedError, 'Please implement the remaining_minutes_in_oven method' end - def preperation_time_in_minutes(layers) - raise NotImplementedError, 'Please implement the preperation_time_in_minutes method' + def preparation_time_in_minutes(layers) + raise NotImplementedError, 'Please implement the preparation_time_in_minutes method' end def total_time_in_minutes(number_of_layers:, actual_minutes_in_oven:) From 28faabc015987fe65d4ceb6a1d27d15d89560bab Mon Sep 17 00:00:00 2001 From: Tim Austin Date: Sun, 19 Jul 2020 12:17:00 -0600 Subject: [PATCH 024/102] new concept exercise - `instance-variables` Introduces `instance-variables` exercise, see design.md. Co-authored-by: Victor Goff Co-authored-by: Jeremy Walker --- .../concept/instance-variables/.docs/after.md | 63 +++++++++++++++++++ .../concept/instance-variables/.docs/hints.md | 39 ++++++++++++ .../instance-variables/.docs/instructions.md | 51 +++++++++++++++ .../instance-variables/.docs/introduction.md | 56 +++++++++++++++++ .../instance-variables/.meta/config.json | 19 ++++++ .../instance-variables/.meta/design.md | 38 +++++++++++ .../instance-variables/.meta/example.rb | 21 +++++++ .../concept/instance-variables/attendee.rb | 21 +++++++ .../instance-variables/attendee_test.rb | 38 +++++++++++ 9 files changed, 346 insertions(+) create mode 100644 exercises/concept/instance-variables/.docs/after.md create mode 100644 exercises/concept/instance-variables/.docs/hints.md create mode 100644 exercises/concept/instance-variables/.docs/instructions.md create mode 100644 exercises/concept/instance-variables/.docs/introduction.md create mode 100644 exercises/concept/instance-variables/.meta/config.json create mode 100644 exercises/concept/instance-variables/.meta/design.md create mode 100644 exercises/concept/instance-variables/.meta/example.rb create mode 100644 exercises/concept/instance-variables/attendee.rb create mode 100644 exercises/concept/instance-variables/attendee_test.rb diff --git a/exercises/concept/instance-variables/.docs/after.md b/exercises/concept/instance-variables/.docs/after.md new file mode 100644 index 0000000000..4bfd22f6d4 --- /dev/null +++ b/exercises/concept/instance-variables/.docs/after.md @@ -0,0 +1,63 @@ +## Key Points: + +- When a class' `.new` method is called to create an object instance, the `.initialize` method is passed all arguments to initialize the instance's state. +- instance variable names are prefixed with `@`. +- instance variables default to `nil` until they are explicitly set. +- instance variables are private by default, and they should be manipulated with getters and setters + +```ruby +class Backpack + initialize(owner) + @owner = owner + end + + def owner + @owner + end + + def owner=(new_owner) + @owner = new_owner + end +end +``` + +- Methods named with a trailing `=` are recognized as setters by ruby, and allow the optional use of the assignment syntax, e.g. `Backpack.new("Sven").owner = "Ayah"` +- Getters and setters can be shortened using the `attr_reader`, `attr_writer`, and `attr_accessor` methods: + - `attr_reader`: Create getters for the symbols listed + - `attr_writer`: Create setters for the symbols listed + - `attr_accessor`: Create getters and setters for the symbols listed + +```ruby +class Backpack + attr_accessor :owner + + initialize(owner) + @owner = owner + end +end +``` + +- Why use getters and setters rather than the instance variable directly? + - If there was a typo in the previous example (e.g. `@ownar`), it would fail silently, potentially introducing a bug into the system. + - Getters and setters make this explicit, and will raise an error when a typo is made + +## References + +### Initializing object instances + +- [Ruby Guides: Initialize Method][rg-initialize-method] + +### Instance variables + +- [Ruby For Beginners: Instance variables][rfb-instance-variables] +- [Ruby Guides: Instance variables][rg-instance-variables] +- [Ruby User's Guide: Instance variables][rug-instance-variables] +- [Geeks for Geeks: Ruby Getters and Setters Methods][gfg-getter-setters] +- [Mix & Go: Ruby's attr_accessor, attr_reader, attr_writer][mg-attr] + +[mg-attr]: https://mixandgo.com/learn/ruby_attr_accessor_attr_reader_attr_writer +[rfb-instance-variables]: http://ruby-for-beginners.rubymonstas.org/writing_classes/instance_variables.html +[rg-initialize-method]: https://www.rubyguides.com/2019/01/ruby-initialize-method/ +[rg-instance-variables]: https://www.rubyguides.com/2019/07/ruby-instance-variables/ +[rug-instance-variables]: https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/instancevars.html +[gfg-getter-setters]: https://www.geeksforgeeks.org/ruby-getters-and-setters-method/ diff --git a/exercises/concept/instance-variables/.docs/hints.md b/exercises/concept/instance-variables/.docs/hints.md new file mode 100644 index 0000000000..88fd23037d --- /dev/null +++ b/exercises/concept/instance-variables/.docs/hints.md @@ -0,0 +1,39 @@ +## General + +About initializing object instances: + +- [Ruby Guides: Initialize Method][rg-initialize-method] + +About instance variables: + +- [Ruby For Beginners: Instance variables][rfb-instance-variables] +- [Ruby Guides: Instance variables][rg-instance-variables] +- [Ruby User's Guide: Instance variables][rug-instance-variables] +- [Geeks for Geeks: Ruby Getters and Setters Methods][gfg-getter-setters] + +## 1. Make new attendees + +- Using the references, complete the initialize method to save the height to the object's state. + +## 2. How tall is the attendee + +- Create a getter for the saved height state. + +## 3. What is the ride pass's id + +- Create a getter for the pass id. +- It is okay and expected to return `nil` before a pass is issued to the `Attendee`. + +## 4. Allow people to buy a pass + +- Using the `issue_pass!` method, set the instance's state to the argument. + +## 4. Revoke the pass + +- Using the `revoke_pass!` setter method set the instance's state so that no pass exists. + +[rfb-instance-variables]: http://ruby-for-beginners.rubymonstas.org/writing_classes/instance_variables.html +[rg-initialize-method]: https://www.rubyguides.com/2019/01/ruby-initialize-method/ +[rg-instance-variables]: https://www.rubyguides.com/2019/07/ruby-instance-variables/ +[rug-instance-variables]: https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/instancevars.html +[gfg-getter-setters]: https://www.geeksforgeeks.org/ruby-getters-and-setters-method/ diff --git a/exercises/concept/instance-variables/.docs/instructions.md b/exercises/concept/instance-variables/.docs/instructions.md new file mode 100644 index 0000000000..0a1db63055 --- /dev/null +++ b/exercises/concept/instance-variables/.docs/instructions.md @@ -0,0 +1,51 @@ +Working with an amusement park, you've been handed a specification to design a system to administer attendance and rides. You've been tasked with modeling the Attendee (person visiting the park). + +## 1. Make new attendees + +Implement the `initialize` method of the `Attendee` class, it should take a height (in centimeters) and store it as an instance variable + +```ruby +Attendee.new(106) +# => # +``` + +## 2. How tall is the attendee + +Implement the `height` getter of the `Attendee` class, it should return the instances height + +```ruby +Attendee.new(106).height +# => 106 +``` + +## 3. What is the ride pass' id + +Not all attendees have bought a ride pass, but we need to know if they have a pass or not. Implement the `pass_id` getter for the `Attendee` class, it should return the instance's pass_id or `nil` if the Attendee doesn't have one. + +```ruby +Attendee.new(106).pass_id +# => nil +``` + +## 4. Allow people to buy a pass + +Implement `issue_pass!` to mutate the state of the instance, and set the pass id instance varaiable to the argument. It should return the pass id. + +```ruby +attendee = Attendee.new(106) +attendee.issue_pass!(42) +attendee.pass_id +# => 42 +``` + +## 4. Revoke the pass + +Some guests break the rules with unsafe behavior, so the park wants to be able to revoke passes. Implement `revoke_pass` to mutate the state of the instance, and set the pass id to `nil` + +```ruby +attendee = Attendee.new(106) +attendee.issue_pass!(42) +attendee.revoke_pass! +attendee.pass_id +# => nil +``` diff --git a/exercises/concept/instance-variables/.docs/introduction.md b/exercises/concept/instance-variables/.docs/introduction.md new file mode 100644 index 0000000000..b77ec17029 --- /dev/null +++ b/exercises/concept/instance-variables/.docs/introduction.md @@ -0,0 +1,56 @@ +## Object state, instance variables + +Objects can hold their own state by setting _instance variables_, which are created by prefixing `@` to a variable name. + +```ruby +@name = 2 +``` + +Objects usually set their initial state in an `initialize` method, which is automatically called when calling `new` on a class. + +```ruby +class Airplane + def initialize + @wings = 2 + end +end +``` + +The `initialize` method may also take arguments, so that each instance can start with a custom state: + +```ruby +class Suitcase + def initialize(locked) + @locked = locked + end +end +``` + +Consider _instance_ variables to be private from external read and writes. _Instance_ methods should be used for getting and setting instance variables: + +```ruby +class Suitcase + #... + + def locked? # Query methods should be named with a trailing `?` + @locked + end + + def unlock! # Methods which mutate state should have trailing `!` + @locked = false + end +end +``` + +## Nil + +[Nil][nil-dictionary] is an English word meaning "nothing" or "zero". In Ruby, `nil` is used to express the _absence_ of an object. In other programming languages, `null` or `none` values may play a similar role. + +```ruby +# I do not have a favorite color +favorite_color = nil +``` + +Ruby gives any instance variable the default value of `nil` when it is first encountered, until it is set otherwise. + +[nil-dictionary]: https://www.merriam-webster.com/dictionary/nil diff --git a/exercises/concept/instance-variables/.meta/config.json b/exercises/concept/instance-variables/.meta/config.json new file mode 100644 index 0000000000..9771b33b79 --- /dev/null +++ b/exercises/concept/instance-variables/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + { + "github_username": "neenjaw", + "exercism_username": "neenjaw" + }, + { + "github_username": "iHiD", + "exercism_username": "iHiD" + } + ], + "contributors": [ + { + "github_username": "kotp", + "exercism_username": "kotp" + } + ], + "language_versions": ">=2.6.6" +} diff --git a/exercises/concept/instance-variables/.meta/design.md b/exercises/concept/instance-variables/.meta/design.md new file mode 100644 index 0000000000..b7590fdb18 --- /dev/null +++ b/exercises/concept/instance-variables/.meta/design.md @@ -0,0 +1,38 @@ +## Goal + +The goal of this exercise is to teach the student the basics of the concept instance variables and "nil" in Ruby. + +## Learning objectives + +- Know that objects can store state using instance variables +- Know that instance variables should be treated as private and to use getter and setter methods +- Know that `nil` is a Ruby object used to represent "nothingness" +- Know that instance variables are `nil` before they are assigned otherwise + +## Out of scope + +- Boolean values (True/False) +- Truthy/Falsey-ness + +## Concepts + +- `instance-variables` +- `nil` + +## Prerequisites + +- `basics` + +## Resources + +### After + +- [The nil value in Ruby](https://medium.com/rubycademy/the-nil-value-in-ruby-d60e6a3642b9#:~:text=method%20implementation-,The%20nil%20value,%E2%80%9Clack%20of%20an%20object%E2%80%9D.&text=Unlike%20other%20languages%2C%20the%20nil,the%20non%2Dinstantiable%20NilClass%20class.) + +## Representer + +This exercise does not require any specific representation logic to be added to the [representer](https://github.com/exercism/ruby-representer). + +## Analyzer + +This exercise does not require any specific analyzer logic to be added to the [analyzer](https://github.com/exercism/ruby-analyzer). diff --git a/exercises/concept/instance-variables/.meta/example.rb b/exercises/concept/instance-variables/.meta/example.rb new file mode 100644 index 0000000000..49b0af1aec --- /dev/null +++ b/exercises/concept/instance-variables/.meta/example.rb @@ -0,0 +1,21 @@ +class Attendee + def initialize(height) + @height = height + end + + def height + @height + end + + def pass_id + @pass_id + end + + def issue_pass!(pass_id) + @pass_id = pass_id + end + + def revoke_pass! + @pass_id = nil + end +end diff --git a/exercises/concept/instance-variables/attendee.rb b/exercises/concept/instance-variables/attendee.rb new file mode 100644 index 0000000000..a6aa600021 --- /dev/null +++ b/exercises/concept/instance-variables/attendee.rb @@ -0,0 +1,21 @@ +class Attendee + def initialize(height) + raise NotImplementedError, 'Implement the initialize method' + end + + def height + raise NotImplementedError, 'Implement the height method' + end + + def pass_id + raise NotImplementedError, 'Implement the pass_id method' + end + + def issue_pass!(pass_id) + raise NotImplementedError, 'Implement the issue_pass! method' + end + + def revoke_pass! + raise NotImplementedError, 'Implement the revoke_pass! method' + end +end diff --git a/exercises/concept/instance-variables/attendee_test.rb b/exercises/concept/instance-variables/attendee_test.rb new file mode 100644 index 0000000000..d6232d2070 --- /dev/null +++ b/exercises/concept/instance-variables/attendee_test.rb @@ -0,0 +1,38 @@ +require 'minitest/autorun' +require_relative 'attendee' + +class AttendeeTest < Minitest::Test + def test_new_instance + height = 100 + assert_equal Attendee, Attendee.new(height).class + end + + def test_new_instance_height + height = 100 + assert_equal height, Attendee.new(height).height + end + + def test_new_instance_pass_id + height = 100 + assert_nil Attendee.new(height).pass_id + end + + def test_issue_pass + height = 100 + attendee = Attendee.new(height) + + pass_id = 1 + attendee.issue_pass!(pass_id) + + assert_equal pass_id, attendee.pass_id + end + + def test_has_pass_after_revoked + height = 100 + attendee = Attendee.new(height) + pass_id = 1 + attendee.issue_pass!(pass_id) + attendee.revoke_pass! + refute attendee.pass_id + end +end From 07ed86f33b2d64b668c507e08f355c42e1dbb9dd Mon Sep 17 00:00:00 2001 From: Tim Austin Date: Sun, 19 Jul 2020 12:20:13 -0600 Subject: [PATCH 025/102] new exercise - `booleans` Introduces `booleans` exercise, see design.md for details. Co-authored-by: Victor Goff Co-authored-by: Jeremy Walker --- exercises/concept/booleans/.docs/after.md | 55 +++++++++++++ exercises/concept/booleans/.docs/hints.md | 28 +++++++ .../concept/booleans/.docs/instructions.md | 30 +++++++ .../concept/booleans/.docs/introduction.md | 60 ++++++++++++++ exercises/concept/booleans/.meta/config.json | 19 +++++ exercises/concept/booleans/.meta/design.md | 48 +++++++++++ exercises/concept/booleans/.meta/example.rb | 29 +++++++ exercises/concept/booleans/attendee.rb | 29 +++++++ exercises/concept/booleans/attendee_test.rb | 81 +++++++++++++++++++ 9 files changed, 379 insertions(+) create mode 100644 exercises/concept/booleans/.docs/after.md create mode 100644 exercises/concept/booleans/.docs/hints.md create mode 100644 exercises/concept/booleans/.docs/instructions.md create mode 100644 exercises/concept/booleans/.docs/introduction.md create mode 100644 exercises/concept/booleans/.meta/config.json create mode 100644 exercises/concept/booleans/.meta/design.md create mode 100644 exercises/concept/booleans/.meta/example.rb create mode 100644 exercises/concept/booleans/attendee.rb create mode 100644 exercises/concept/booleans/attendee_test.rb diff --git a/exercises/concept/booleans/.docs/after.md b/exercises/concept/booleans/.docs/after.md new file mode 100644 index 0000000000..f890230093 --- /dev/null +++ b/exercises/concept/booleans/.docs/after.md @@ -0,0 +1,55 @@ +## True, False + +- `true` and `false` are used to represent boolean logical states. + - They are singleton instances of the [`TrueClass`][true-class] and [`FalseClass`][false-class] objects. + - they may occur as literals in code, or as the result of logical (`&&`, `||`, `!`) or [comparison][comparable-class] (`<`, `>`, `==`) methods. + +## _Truthy_ and _falsey_ + +- When not using strict Boolean values, _truthy_ and _falsey_ evaluation rules are applied: + + - Only `false` and `nil` evaluates as _falsey_. + - Everything else evaluates as _truthy_. + + ```ruby + # A simplified definition + def falsey + nil || false + end + + def truthy + not falsey + end + ``` + +- It is common to use _truthy_ and _falsey_ values to determine the outcome of [conditional statements][control-expressions]. + + - `if`…`else` exists as a construct, similar to the [_C-family_ of programming languages][c-family] + - it is often more idiomatic to use `if` and `unless` as [expression modifiers to "guard" an expression][if-modifier] + + ```ruby + 1 + 1 if truthy + # => this will evaluate and return 2 + + 2 + 2 if falsey + # => the numbers are not added because of the modifier, nil is returned + + 3 + 3 unless truthy + # => the numbers are not added because of the modifier, nil is returned + + 4 + 4 unless falsey + # => this will evaluate and return 8 + ``` + +[c-family]: https://en.wikipedia.org/wiki/List_of_C-family_programming_languages +[control-expressions]: https://docs.ruby-lang.org/en/master/syntax/control_expressions_rdoc.html +[if-modifier]: https://docs.ruby-lang.org/en/master/syntax/control_expressions_rdoc.html#label-Modifier+if+and+unless +[true-class]: https://docs.ruby-lang.org/en/master/TrueClass.html +[false-class]: https://docs.ruby-lang.org/en/master/FalseClass.html +[nil-class]: https://docs.ruby-lang.org/en/master/NilClass.html +[comparable-class]: https://docs.ruby-lang.org/en/master/Comparable.html +[constants]: https://www.rubyguides.com/2017/07/ruby-constants/ +[integer-class]: https://docs.ruby-lang.org/en/master/Integer.html +[kernel-class]: https://docs.ruby-lang.org/en/master/Kernel.html +[methods]: https://launchschool.com/books/ruby/read/methods +[returns]: https://www.freecodecamp.org/news/idiomatic-ruby-writing-beautiful-code-6845c830c664/ diff --git a/exercises/concept/booleans/.docs/hints.md b/exercises/concept/booleans/.docs/hints.md new file mode 100644 index 0000000000..cf56e9a576 --- /dev/null +++ b/exercises/concept/booleans/.docs/hints.md @@ -0,0 +1,28 @@ +## General + +Review: + +- [Ruby for beginners: Nothingness and the truth][rfb-nothingness-and-truth] + +## 1. Check if an attendee has a ride pass + +- Convert the pass_id to a boolean object. +- Look at the [`BasicObject`][basicobject-class] class, it contains methods which most classes inherit. + +## 2. Check if an attendee fits a ride + +- Compare the ride's minimum height to the attendee's height. +- Look at the [`Comparable`][comparable-module] module, it contains methods for comparing objects which can be used when they are included. + - The [Integer][integer-class] class includes the [`Comparable`][comparable-module] module. + +## 3. Check if an attendee is allowed to ride + +- Combine the instance methods you've created using a [boolean operator][pr-boolean-operator] to return the result. + +[pr-boolean-operator]: https://ruby-doc.com/docs/ProgrammingRuby/html/tut_expressions.html#UG +[rfb-nothingness-and-truth]: http://ruby-for-beginners.rubymonstas.org/conditionals/nothing_and_truth.html +[basicobject-class]: https://docs.ruby-lang.org/en/master/BasicObject.html +[comparable-module]: https://docs.ruby-lang.org/en/master/Comparable.html +[integer-class]: https://docs.ruby-lang.org/en/master/Integer.html +[kernel-class]: https://docs.ruby-lang.org/en/master/Kernel.html +[methods]: https://launchschool.com/books/ruby/read/methods diff --git a/exercises/concept/booleans/.docs/instructions.md b/exercises/concept/booleans/.docs/instructions.md new file mode 100644 index 0000000000..b19db961d5 --- /dev/null +++ b/exercises/concept/booleans/.docs/instructions.md @@ -0,0 +1,30 @@ +Continuing your work with the amusement park, you are tasked with writing some utility methods to facilitate checking an attendee can use a ride. + +## 1. Check if an attendee has a ride pass + +Implement the `pass?` method to return a boolean (`true`/`false`) value based on the presence of a ride pass. + +```ruby +Attendee.new(100).has_pass? +# => false +``` + +## 2. Check if an attendee fits a ride + +Implement the `fits_ride?` method to see if an attendee fits a ride based on their height and the minimum height of required by the ride. + +```ruby +Attendee.new(140).fits_ride?(100) +# => true +``` + +## 3. Check if an attendee is allowed to ride + +Implement the `allowed_to_ride?` method to see if an attendee is allowed to go on a ride. The ride's required minimum height is provided as an argument. An attendee must have a ride pass and be able to fit the ride. + +```ruby +attendee = Attendee.new(100) +attendee.issue_pass!(42) +attendee.allowed_to_ride(120) +# => false +``` diff --git a/exercises/concept/booleans/.docs/introduction.md b/exercises/concept/booleans/.docs/introduction.md new file mode 100644 index 0000000000..aef2c5f33d --- /dev/null +++ b/exercises/concept/booleans/.docs/introduction.md @@ -0,0 +1,60 @@ +## True and False + +True and false logical states are represented with `true` and `false` in Ruby. These may either be used as literals on their own, or as a result of logical or comparison methods. + +```ruby +happy = true +sad = false + +true && false +# => false + +1 < 2 +# => true +``` + +## _Truthy_ and _falsey_ + +When evaluating objects in `if` statements or other boolean contexts, all objects evaluate as _truthy_ **except** for `false` and `nil`. + +## Control flow + +_Truthy_ and _falsey_ evaluations are useful in the context of control flow. Like in procedural languages, Ruby has an `if`...`else` construct, but it may be more common to use `if` as a "guarding" statement to modify the evaluation of an expression. + +```ruby +def falsey + nil || false +end + +def truthy + not falsey +end + +if truthy + # this block is evaluated +end + +if falsey + # this block is not evaluated +else + # this block is evaluated +end + +1 + 1 if truthy +# => this will evaluate and return 2 + +2 + 2 if falsey +# => the numbers are not added because of the modifier, nil is returned +``` + +Ruby provides `unless` to make code read well. E.g.) Rather than `eat_desert if not too_full`, we can also write `eat_desert unless too_full`. + +```ruby +3 + 3 unless truthy +# => the numbers are not added because of the modifier, nil is returned + +4 + 4 unless falsey +# => this will evaluate and return 8 +``` + +[nil-dictionary]: https://www.merriam-webster.com/dictionary/nil diff --git a/exercises/concept/booleans/.meta/config.json b/exercises/concept/booleans/.meta/config.json new file mode 100644 index 0000000000..8c14b3557c --- /dev/null +++ b/exercises/concept/booleans/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + { + "github_username": "neenjaw", + "exercism_username": "neenjaw" + } + ], + "contributors": [ + { + "github_username": "kotp", + "exercism_username": "kotp" + }, + { + "github_username": "iHiD", + "exercism_username": "iHiD" + } + ], + "language_versions": ">=2.6.6" +} diff --git a/exercises/concept/booleans/.meta/design.md b/exercises/concept/booleans/.meta/design.md new file mode 100644 index 0000000000..7467e78dd0 --- /dev/null +++ b/exercises/concept/booleans/.meta/design.md @@ -0,0 +1,48 @@ +## Goal + +The goal of this exercise is to teach the student the basics of the Concept of "nil" in Ruby. + +## Learning objectives + +- Know that `true` is a Ruby object used to represent logical `true` +- Know that `false` is a Ruby object used to represent logical `false` +- Know that `nil` is a Ruby object used to represent "nothingness" +- Know that everything except `false` and `nil` is truthy +- Know that `nil` is falsey + +## Out of scope + +- None as it relates to this concept + +## Reference + +- `TrueClass` +- `FalseClass` +- `NilClass` + +## Concepts + +- `boolean` +- `nil` + +## Prerequisites + +- `basics` + +## Resources + +### Hints + +- [Data Types in Ruby - True, False, and Nil Explained with Examples](https://www.freecodecamp.org/news/data-types-in-ruby-true-false-and-nil-explained-with-examples/) + +### After + +- [The nil value in Ruby](https://medium.com/rubycademy/the-nil-value-in-ruby-d60e6a3642b9#:~:text=method%20implementation-,The%20nil%20value,%E2%80%9Clack%20of%20an%20object%E2%80%9D.&text=Unlike%20other%20languages%2C%20the%20nil,the%20non%2Dinstantiable%20NilClass%20class.) + +## Representer + +This exercise does not require any specific representation logic to be added to the [representer](https://github.com/exercism/ruby-representer). + +## Analyzer + +This exercise does not require any specific analyzer logic to be added to the [analyzer](https://github.com/exercism/ruby-analyzer). diff --git a/exercises/concept/booleans/.meta/example.rb b/exercises/concept/booleans/.meta/example.rb new file mode 100644 index 0000000000..2f9e4566b5 --- /dev/null +++ b/exercises/concept/booleans/.meta/example.rb @@ -0,0 +1,29 @@ +class Attendee + attr_reader :height, :pass_id + + def initialize(height) + @height = height + end + + def issue_pass!(pass_id) + @pass_id = pass_id + end + + def revoke_pass! + @pass_id = nil + end + + # Do not edit above methods, add your own methods below. + + def pass? + !pass_id.nil? + end + + def fits_ride?(ride_minimum_height) + height >= ride_minimum_height + end + + def allowed_to_ride?(ride_minimum_height) + pass_id && fits_ride?(ride_minimum_height) + end +end diff --git a/exercises/concept/booleans/attendee.rb b/exercises/concept/booleans/attendee.rb new file mode 100644 index 0000000000..11fdfb5491 --- /dev/null +++ b/exercises/concept/booleans/attendee.rb @@ -0,0 +1,29 @@ +class Attendee + attr_reader :height, :pass_id + + def initialize(height) + @height = height + end + + def issue_pass!(pass_id) + @pass_id = pass_id + end + + def revoke_pass! + @pass_id = nil + end + + # Do not edit above methods, add your own methods below. + + def pass? + raise NotImplementedError, 'Please implement the pass? method' + end + + def fits_ride?(ride_minimum_height) + raise NotImplementedError, 'Please implement the fits_ride? method' + end + + def allowed_to_ride?(ride_minimum_height) + raise NotImplementedError, 'Please implement the allowed_to_ride? method' + end +end diff --git a/exercises/concept/booleans/attendee_test.rb b/exercises/concept/booleans/attendee_test.rb new file mode 100644 index 0000000000..2defdddedc --- /dev/null +++ b/exercises/concept/booleans/attendee_test.rb @@ -0,0 +1,81 @@ +require 'minitest/autorun' +require_relative 'attendee' + +class AttendeeTest < Minitest::Test + # Tests carried over from `instance-variables` exercise + + def test_new_instance + height = 100 + assert_equal Attendee, Attendee.new(height).class + end + + def test_new_instance_height + height = 100 + assert_equal height, Attendee.new(height).height + end + + def test_new_instance_pass_id + height = 100 + assert_nil Attendee.new(height).pass_id + end + + def test_issue_pass + height = 100 + attendee = Attendee.new(height) + + pass_id = 1 + attendee.issue_pass!(pass_id) + + assert_equal pass_id, attendee.pass_id + end + + def test_pass_after_revoked + height = 100 + attendee = Attendee.new(height) + pass_id = 1 + attendee.issue_pass!(pass_id) + attendee.revoke_pass! + refute attendee.pass_id + end + + # New tests for `booleans` exercise + + def test_new_instance_doesnt_have_pass + refute Attendee.new(100).pass? + end + + def test_when_issued_pass + attendee = Attendee.new(100) + attendee.issue_pass!(1) + assert attendee.pass? + end + + def test_when_revoked_doesnt_have_pass + attendee = Attendee.new(100) + attendee.issue_pass!(1) + attendee.revoke_pass! + refute attendee.pass? + end + + def test_fits_ride_exactly + assert Attendee.new(100).fits_ride?(100) + end + + def test_fits_small_ride + assert Attendee.new(100).fits_ride?(80) + end + + def test_doesnt_fit_big_ride + refute Attendee.new(100).fits_ride?(110) + end + + def test_fits_ride_but_no_pass + refute Attendee.new(100).allowed_to_ride?(100) + end + + def test_fits_ride_and_pass + attendee = Attendee.new(100) + attendee.issue_pass!(1) + assert attendee.allowed_to_ride?(100) + end +end From e3cbad898825c4b74735ce08a175096a2b348a1d Mon Sep 17 00:00:00 2001 From: Viktor Date: Wed, 22 Jul 2020 13:59:10 +0200 Subject: [PATCH 026/102] Ruby remove booleans from numbers * Remove booleans from numbers * Add original PR contributors * Remove basics concept from prerequisites --- exercises/concept/numbers/.docs/after.md | 2 +- exercises/concept/numbers/.docs/introduction.md | 2 -- exercises/concept/numbers/.meta/config.json | 10 ++++++++++ exercises/concept/numbers/.meta/design.md | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/exercises/concept/numbers/.docs/after.md b/exercises/concept/numbers/.docs/after.md index 9ad3149117..92750518df 100644 --- a/exercises/concept/numbers/.docs/after.md +++ b/exercises/concept/numbers/.docs/after.md @@ -33,7 +33,7 @@ b.class #=> true ``` -An `if` statement can be used to conditionally execute code. The condition of an `if` statement does not have to be only `true` or `false`. It can be any value. But it's important to know that any value other than `nil` and `false` (_truthy_ values) will be treated as `true`, meaning that the code inside the `if` statement will be executed. +An `if` statement can be used to conditionally execute code: ```ruby x = 5 diff --git a/exercises/concept/numbers/.docs/introduction.md b/exercises/concept/numbers/.docs/introduction.md index eae5bb9f6b..bf9d71ae7d 100644 --- a/exercises/concept/numbers/.docs/introduction.md +++ b/exercises/concept/numbers/.docs/introduction.md @@ -20,5 +20,3 @@ else # Execute logic in all other cases end ``` - -The condition of an `if` statement does not have to be only `true` or `false`. It can be any value. But it's important to know that any value other than `nil` and `false` (_truthy_ values) will be treated as `true`, meaning that the code inside the `if` statement will be executed. diff --git a/exercises/concept/numbers/.meta/config.json b/exercises/concept/numbers/.meta/config.json index 5433c10617..f2f5a942e5 100644 --- a/exercises/concept/numbers/.meta/config.json +++ b/exercises/concept/numbers/.meta/config.json @@ -5,5 +5,15 @@ "exercism_username": "dvik1950" } ], + "contributors": [ + { + "github_username": "kotp", + "exercism_username": "kotp" + }, + { + "github_username": "iHiD", + "exercism_username": "iHiD" + } + ], "forked_from": ["csharp/numbers"] } diff --git a/exercises/concept/numbers/.meta/design.md b/exercises/concept/numbers/.meta/design.md index f247e44495..85b120bbc8 100644 --- a/exercises/concept/numbers/.meta/design.md +++ b/exercises/concept/numbers/.meta/design.md @@ -26,7 +26,7 @@ The Concepts this exercise unlocks are: This exercise's prerequisite Concepts are: -- `basics`: know how to define methods. +- `booleans`: know about `true`/`false` and truthy/falsey values. ## Representer From ea26ae6143953e25f433b78438bb624c0df788aa Mon Sep 17 00:00:00 2001 From: ynfle <23086821+ynfle@users.noreply.github.com> Date: Sun, 23 Aug 2020 00:15:45 +0300 Subject: [PATCH 027/102] Fix missing link reference --- exercises/concept/basics/.docs/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/basics/.docs/introduction.md b/exercises/concept/basics/.docs/introduction.md index bef0b83a5f..4808c0c153 100644 --- a/exercises/concept/basics/.docs/introduction.md +++ b/exercises/concept/basics/.docs/introduction.md @@ -1,4 +1,4 @@ -Ruby is a dynamic [object-oriented language]. Everything in Ruby is an [object][object]. +Ruby is a dynamic [object-oriented language][object-oriented-programming]. Everything in Ruby is an [object][object]. There are two primary ways to assign objects to names in Ruby - using variables or constants. Variables are always written in [snake case][snake-case]. A variable can reference different objects over its lifetime. For example, `my_first_variable` can be defined and redefined many times using the `=` operator: From 306e9a5489d358c0ac051d07d362932bbfd869e6 Mon Sep 17 00:00:00 2001 From: Jonathan Yeong Date: Sat, 3 Oct 2020 07:08:07 -0700 Subject: [PATCH 028/102] Normalize naming for method references * Normalize naming for method references * Add some missed methods in the instructions.md --- exercises/concept/basics/lasagna.rb | 6 +++--- exercises/concept/booleans/.docs/instructions.md | 6 +++--- exercises/concept/booleans/attendee.rb | 6 +++--- exercises/concept/instance-variables/.docs/hints.md | 4 ++-- .../concept/instance-variables/.docs/instructions.md | 10 +++++----- exercises/concept/instance-variables/attendee.rb | 10 +++++----- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/exercises/concept/basics/lasagna.rb b/exercises/concept/basics/lasagna.rb index 17e61dea0a..09736d8cbb 100644 --- a/exercises/concept/basics/lasagna.rb +++ b/exercises/concept/basics/lasagna.rb @@ -1,13 +1,13 @@ class Lasagna def remaining_minutes_in_oven(actual_minutes_in_oven) - raise NotImplementedError, 'Please implement the remaining_minutes_in_oven method' + raise NotImplementedError, 'Please implement the Lasagna#remaining_minutes_in_oven method' end def preparation_time_in_minutes(layers) - raise NotImplementedError, 'Please implement the preparation_time_in_minutes method' + raise NotImplementedError, 'Please implement the Lasagna#preparation_time_in_minutes method' end def total_time_in_minutes(number_of_layers:, actual_minutes_in_oven:) - raise NotImplementedError, 'Please implement the total_time_in_minutes method' + raise NotImplementedError, 'Please implement the Lasagna#total_time_in_minutes method' end end diff --git a/exercises/concept/booleans/.docs/instructions.md b/exercises/concept/booleans/.docs/instructions.md index b19db961d5..29311a7155 100644 --- a/exercises/concept/booleans/.docs/instructions.md +++ b/exercises/concept/booleans/.docs/instructions.md @@ -2,7 +2,7 @@ Continuing your work with the amusement park, you are tasked with writing some u ## 1. Check if an attendee has a ride pass -Implement the `pass?` method to return a boolean (`true`/`false`) value based on the presence of a ride pass. +Implement the `Attendee#pass?` method to return a boolean (`true`/`false`) value based on the presence of a ride pass. ```ruby Attendee.new(100).has_pass? @@ -11,7 +11,7 @@ Attendee.new(100).has_pass? ## 2. Check if an attendee fits a ride -Implement the `fits_ride?` method to see if an attendee fits a ride based on their height and the minimum height of required by the ride. +Implement the `Attendee#fits_ride?` method to see if an attendee fits a ride based on their height and the minimum height of required by the ride. ```ruby Attendee.new(140).fits_ride?(100) @@ -20,7 +20,7 @@ Attendee.new(140).fits_ride?(100) ## 3. Check if an attendee is allowed to ride -Implement the `allowed_to_ride?` method to see if an attendee is allowed to go on a ride. The ride's required minimum height is provided as an argument. An attendee must have a ride pass and be able to fit the ride. +Implement the `Attendee#allowed_to_ride?` method to see if an attendee is allowed to go on a ride. The ride's required minimum height is provided as an argument. An attendee must have a ride pass and be able to fit the ride. ```ruby attendee = Attendee.new(100) diff --git a/exercises/concept/booleans/attendee.rb b/exercises/concept/booleans/attendee.rb index 11fdfb5491..c93d32b608 100644 --- a/exercises/concept/booleans/attendee.rb +++ b/exercises/concept/booleans/attendee.rb @@ -16,14 +16,14 @@ def revoke_pass! # Do not edit above methods, add your own methods below. def pass? - raise NotImplementedError, 'Please implement the pass? method' + raise NotImplementedError, 'Please implement the Attendee#pass? method' end def fits_ride?(ride_minimum_height) - raise NotImplementedError, 'Please implement the fits_ride? method' + raise NotImplementedError, 'Please implement the Attendee#fits_ride? method' end def allowed_to_ride?(ride_minimum_height) - raise NotImplementedError, 'Please implement the allowed_to_ride? method' + raise NotImplementedError, 'Please implement the Attendee#allowed_to_ride? method' end end diff --git a/exercises/concept/instance-variables/.docs/hints.md b/exercises/concept/instance-variables/.docs/hints.md index 88fd23037d..193b842194 100644 --- a/exercises/concept/instance-variables/.docs/hints.md +++ b/exercises/concept/instance-variables/.docs/hints.md @@ -26,11 +26,11 @@ About instance variables: ## 4. Allow people to buy a pass -- Using the `issue_pass!` method, set the instance's state to the argument. +- Using the `Attendee#issue_pass!` method, set the instance's state to the argument. ## 4. Revoke the pass -- Using the `revoke_pass!` setter method set the instance's state so that no pass exists. +- Using the `Attendee#revoke_pass!` setter method set the instance's state so that no pass exists. [rfb-instance-variables]: http://ruby-for-beginners.rubymonstas.org/writing_classes/instance_variables.html [rg-initialize-method]: https://www.rubyguides.com/2019/01/ruby-initialize-method/ diff --git a/exercises/concept/instance-variables/.docs/instructions.md b/exercises/concept/instance-variables/.docs/instructions.md index 0a1db63055..c2fc45e37d 100644 --- a/exercises/concept/instance-variables/.docs/instructions.md +++ b/exercises/concept/instance-variables/.docs/instructions.md @@ -2,7 +2,7 @@ Working with an amusement park, you've been handed a specification to design a s ## 1. Make new attendees -Implement the `initialize` method of the `Attendee` class, it should take a height (in centimeters) and store it as an instance variable +Implement the `Attendee#initialize` method of the `Attendee` class, it should take a height (in centimeters) and store it as an instance variable ```ruby Attendee.new(106) @@ -11,7 +11,7 @@ Attendee.new(106) ## 2. How tall is the attendee -Implement the `height` getter of the `Attendee` class, it should return the instances height +Implement the `Attendee#height` getter of the `Attendee` class, it should return the instances height ```ruby Attendee.new(106).height @@ -20,7 +20,7 @@ Attendee.new(106).height ## 3. What is the ride pass' id -Not all attendees have bought a ride pass, but we need to know if they have a pass or not. Implement the `pass_id` getter for the `Attendee` class, it should return the instance's pass_id or `nil` if the Attendee doesn't have one. +Not all attendees have bought a ride pass, but we need to know if they have a pass or not. Implement the `Attendee#pass_id` getter for the `Attendee` class, it should return the instance's pass_id or `nil` if the Attendee doesn't have one. ```ruby Attendee.new(106).pass_id @@ -29,7 +29,7 @@ Attendee.new(106).pass_id ## 4. Allow people to buy a pass -Implement `issue_pass!` to mutate the state of the instance, and set the pass id instance varaiable to the argument. It should return the pass id. +Implement `Attendee#issue_pass!` to mutate the state of the instance, and set the pass id instance varaiable to the argument. It should return the pass id. ```ruby attendee = Attendee.new(106) @@ -40,7 +40,7 @@ attendee.pass_id ## 4. Revoke the pass -Some guests break the rules with unsafe behavior, so the park wants to be able to revoke passes. Implement `revoke_pass` to mutate the state of the instance, and set the pass id to `nil` +Some guests break the rules with unsafe behavior, so the park wants to be able to revoke passes. Implement `Attendee#revoke_pass` to mutate the state of the instance, and set the pass id to `nil` ```ruby attendee = Attendee.new(106) diff --git a/exercises/concept/instance-variables/attendee.rb b/exercises/concept/instance-variables/attendee.rb index a6aa600021..ca3a1a088e 100644 --- a/exercises/concept/instance-variables/attendee.rb +++ b/exercises/concept/instance-variables/attendee.rb @@ -1,21 +1,21 @@ class Attendee def initialize(height) - raise NotImplementedError, 'Implement the initialize method' + raise NotImplementedError, 'Implement the Attendee#initialize method' end def height - raise NotImplementedError, 'Implement the height method' + raise NotImplementedError, 'Implement the Attendee#height method' end def pass_id - raise NotImplementedError, 'Implement the pass_id method' + raise NotImplementedError, 'Implement the Attendee#pass_id method' end def issue_pass!(pass_id) - raise NotImplementedError, 'Implement the issue_pass! method' + raise NotImplementedError, 'Implement the Attendee#issue_pass! method' end def revoke_pass! - raise NotImplementedError, 'Implement the revoke_pass! method' + raise NotImplementedError, 'Implement the Attendee#revoke_pass! method' end end From 620c87f5b350b55ce2a0de644e49189db978b768 Mon Sep 17 00:00:00 2001 From: Jonathan Yeong Date: Tue, 6 Oct 2020 06:58:46 -0700 Subject: [PATCH 029/102] Update log line level instructions It now follows the same format as the other instruction files for Ruby. --- exercises/concept/strings/.docs/instructions.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/concept/strings/.docs/instructions.md b/exercises/concept/strings/.docs/instructions.md index e8f6d0e01a..a12ad4eddf 100644 --- a/exercises/concept/strings/.docs/instructions.md +++ b/exercises/concept/strings/.docs/instructions.md @@ -12,7 +12,7 @@ You have three tasks, each of which will take a log line and ask you to do somet ## 1. Get message from a log line -Implement a method to return a log line's message: +Implement the `LogLineParser.message` method to return a log line's message: ```ruby LogLineParser.message('[ERROR]: Invalid operation') @@ -28,7 +28,7 @@ LogLineParser.message('[WARNING]: Disk almost full\r\n') ## 2. Get log level from a log line -Implement a method to return a log line's log level, which should be returned in lowercase: +Implement the `LogLineParser.log_level` method to return a log line's log level, which should be returned in lowercase: ```ruby LogLineParser.log_level('[ERROR]: Invalid operation') @@ -37,7 +37,7 @@ LogLineParser.log_level('[ERROR]: Invalid operation') ## 3. Reformat a log line -Implement a method that reformats the log line, putting the message first and the log level after it in parentheses: +Implement the `LogLineParser.reformat` method that reformats the log line, putting the message first and the log level after it in parentheses: ```ruby LogLineParser.reformat('[INFO]: Operation completed') From f27b31254c2bc2887600881b6d0d4604b2a43470 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Wed, 14 Oct 2020 18:05:44 +0200 Subject: [PATCH 030/102] Add stubs for concept documents --- concepts/arrays/about.md | 1 + concepts/arrays/links.json | 1 + concepts/basics/about.md | 1 + concepts/basics/links.json | 1 + concepts/blocks/about.md | 1 + concepts/blocks/links.json | 1 + concepts/booleans/about.md | 1 + concepts/booleans/links.json | 1 + concepts/classes/about.md | 1 + concepts/classes/links.json | 1 + concepts/conditionals/about.md | 1 + concepts/conditionals/links.json | 1 + concepts/floating-point-numbers/about.md | 1 + concepts/floating-point-numbers/links.json | 1 + concepts/instance-variables/about.md | 1 + concepts/instance-variables/links.json | 1 + concepts/loops/about.md | 1 + concepts/loops/links.json | 1 + concepts/nil/about.md | 1 + concepts/nil/links.json | 1 + concepts/numbers/about.md | 1 + concepts/numbers/links.json | 1 + concepts/strings/about.md | 1 + concepts/strings/links.json | 1 + 24 files changed, 24 insertions(+) create mode 100644 concepts/arrays/about.md create mode 100644 concepts/arrays/links.json create mode 100644 concepts/basics/about.md create mode 100644 concepts/basics/links.json create mode 100644 concepts/blocks/about.md create mode 100644 concepts/blocks/links.json create mode 100644 concepts/booleans/about.md create mode 100644 concepts/booleans/links.json create mode 100644 concepts/classes/about.md create mode 100644 concepts/classes/links.json create mode 100644 concepts/conditionals/about.md create mode 100644 concepts/conditionals/links.json create mode 100644 concepts/floating-point-numbers/about.md create mode 100644 concepts/floating-point-numbers/links.json create mode 100644 concepts/instance-variables/about.md create mode 100644 concepts/instance-variables/links.json create mode 100644 concepts/loops/about.md create mode 100644 concepts/loops/links.json create mode 100644 concepts/nil/about.md create mode 100644 concepts/nil/links.json create mode 100644 concepts/numbers/about.md create mode 100644 concepts/numbers/links.json create mode 100644 concepts/strings/about.md create mode 100644 concepts/strings/links.json diff --git a/concepts/arrays/about.md b/concepts/arrays/about.md new file mode 100644 index 0000000000..c54a50ebfc --- /dev/null +++ b/concepts/arrays/about.md @@ -0,0 +1 @@ +TODO: add information on arrays concept diff --git a/concepts/arrays/links.json b/concepts/arrays/links.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/concepts/arrays/links.json @@ -0,0 +1 @@ +[] diff --git a/concepts/basics/about.md b/concepts/basics/about.md new file mode 100644 index 0000000000..246577017b --- /dev/null +++ b/concepts/basics/about.md @@ -0,0 +1 @@ +TODO: add information on basics concept diff --git a/concepts/basics/links.json b/concepts/basics/links.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/concepts/basics/links.json @@ -0,0 +1 @@ +[] diff --git a/concepts/blocks/about.md b/concepts/blocks/about.md new file mode 100644 index 0000000000..3171aac4f5 --- /dev/null +++ b/concepts/blocks/about.md @@ -0,0 +1 @@ +TODO: add information on blocks concept diff --git a/concepts/blocks/links.json b/concepts/blocks/links.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/concepts/blocks/links.json @@ -0,0 +1 @@ +[] diff --git a/concepts/booleans/about.md b/concepts/booleans/about.md new file mode 100644 index 0000000000..d461152b95 --- /dev/null +++ b/concepts/booleans/about.md @@ -0,0 +1 @@ +TODO: add information on booleans concept diff --git a/concepts/booleans/links.json b/concepts/booleans/links.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/concepts/booleans/links.json @@ -0,0 +1 @@ +[] diff --git a/concepts/classes/about.md b/concepts/classes/about.md new file mode 100644 index 0000000000..608d2f539e --- /dev/null +++ b/concepts/classes/about.md @@ -0,0 +1 @@ +TODO: add information on classes concept diff --git a/concepts/classes/links.json b/concepts/classes/links.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/concepts/classes/links.json @@ -0,0 +1 @@ +[] diff --git a/concepts/conditionals/about.md b/concepts/conditionals/about.md new file mode 100644 index 0000000000..00d25f7851 --- /dev/null +++ b/concepts/conditionals/about.md @@ -0,0 +1 @@ +TODO: add information on conditionals concept diff --git a/concepts/conditionals/links.json b/concepts/conditionals/links.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/concepts/conditionals/links.json @@ -0,0 +1 @@ +[] diff --git a/concepts/floating-point-numbers/about.md b/concepts/floating-point-numbers/about.md new file mode 100644 index 0000000000..4b9cdcc49c --- /dev/null +++ b/concepts/floating-point-numbers/about.md @@ -0,0 +1 @@ +TODO: add information on floating-point-numbers concept diff --git a/concepts/floating-point-numbers/links.json b/concepts/floating-point-numbers/links.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/concepts/floating-point-numbers/links.json @@ -0,0 +1 @@ +[] diff --git a/concepts/instance-variables/about.md b/concepts/instance-variables/about.md new file mode 100644 index 0000000000..ad578931b1 --- /dev/null +++ b/concepts/instance-variables/about.md @@ -0,0 +1 @@ +TODO: add information on instance-variables concept diff --git a/concepts/instance-variables/links.json b/concepts/instance-variables/links.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/concepts/instance-variables/links.json @@ -0,0 +1 @@ +[] diff --git a/concepts/loops/about.md b/concepts/loops/about.md new file mode 100644 index 0000000000..b48612c67f --- /dev/null +++ b/concepts/loops/about.md @@ -0,0 +1 @@ +TODO: add information on loops concept diff --git a/concepts/loops/links.json b/concepts/loops/links.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/concepts/loops/links.json @@ -0,0 +1 @@ +[] diff --git a/concepts/nil/about.md b/concepts/nil/about.md new file mode 100644 index 0000000000..19d56160bb --- /dev/null +++ b/concepts/nil/about.md @@ -0,0 +1 @@ +TODO: add information on nil concept diff --git a/concepts/nil/links.json b/concepts/nil/links.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/concepts/nil/links.json @@ -0,0 +1 @@ +[] diff --git a/concepts/numbers/about.md b/concepts/numbers/about.md new file mode 100644 index 0000000000..36eb002377 --- /dev/null +++ b/concepts/numbers/about.md @@ -0,0 +1 @@ +TODO: add information on numbers concept diff --git a/concepts/numbers/links.json b/concepts/numbers/links.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/concepts/numbers/links.json @@ -0,0 +1 @@ +[] diff --git a/concepts/strings/about.md b/concepts/strings/about.md new file mode 100644 index 0000000000..b046260477 --- /dev/null +++ b/concepts/strings/about.md @@ -0,0 +1 @@ +TODO: add information on strings concept diff --git a/concepts/strings/links.json b/concepts/strings/links.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/concepts/strings/links.json @@ -0,0 +1 @@ +[] From d59b25d77947ced683ab3813cb300e5ccbe6bc7b Mon Sep 17 00:00:00 2001 From: valentin-p <3833193+valentin-p@users.noreply.github.com> Date: Tue, 27 Oct 2020 13:35:21 +0100 Subject: [PATCH 031/102] Fix typos * fixing typos and Prerequisites * run prettier * remove anoying submodule --- exercises/concept/arrays/.meta/design.md | 2 +- exercises/concept/basics/.meta/design.md | 2 +- exercises/concept/strings/.meta/design.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/concept/arrays/.meta/design.md b/exercises/concept/arrays/.meta/design.md index 967ba999f9..c21cae5b86 100644 --- a/exercises/concept/arrays/.meta/design.md +++ b/exercises/concept/arrays/.meta/design.md @@ -31,7 +31,7 @@ This Concepts Exercise's Concepts are: - `arrays`: know of the existence of the `Array` object; know how to define an array; know how to access elements in an array by index; know how to iterate over elements in an array; know of some basic functions. - `each loops`: know how to iterate over a collection. -## Prequisites +## Prerequisites This exercise's prerequisites Concepts are: diff --git a/exercises/concept/basics/.meta/design.md b/exercises/concept/basics/.meta/design.md index 27e6db0f8e..37a20d6f26 100644 --- a/exercises/concept/basics/.meta/design.md +++ b/exercises/concept/basics/.meta/design.md @@ -31,7 +31,7 @@ The Concepts this exercise unlocks are: - `basics`: know what a variable is; know how to define a variable; know how to update a variable; know how to use type inference for variables; know how to define a method; know how to return a value from a method; know how to call a method; know that methods must be defined in classes; know about the `public` access modifier; know about the `static` modifier; know how to define an integer; know how to use mathematical operators on integers; know how to define an integer; know how to use mathematical operators on integers. -## Prequisites +## Prerequisites There are no prerequisites. diff --git a/exercises/concept/strings/.meta/design.md b/exercises/concept/strings/.meta/design.md index 406f5b9d03..d66f045444 100644 --- a/exercises/concept/strings/.meta/design.md +++ b/exercises/concept/strings/.meta/design.md @@ -21,7 +21,7 @@ The Concepts this exercise unlocks are: - `strings-basic`: know of the existence of the `String` object; know of some basic functions (like looking up a character at a position, or slicing the string); know how to do basic string interpolation. -## Prequisites +## Prerequisites There are no prerequisites. From 1185e8edc18ff6cee59837ec2675c67930dd7ad0 Mon Sep 17 00:00:00 2001 From: Jeremy Walker Date: Thu, 29 Oct 2020 00:58:05 +0000 Subject: [PATCH 032/102] Rename basics to lasagna and add temporary keys --- exercises/concept/{basics => lasagna}/.docs/after.md | 0 exercises/concept/{basics => lasagna}/.docs/hints.md | 0 exercises/concept/{basics => lasagna}/.docs/instructions.md | 0 exercises/concept/{basics => lasagna}/.docs/introduction.md | 0 exercises/concept/{basics => lasagna}/.meta/config.json | 6 +++++- exercises/concept/{basics => lasagna}/.meta/design.md | 0 exercises/concept/{basics => lasagna}/.meta/example.rb | 0 exercises/concept/{basics => lasagna}/lasagna.rb | 0 exercises/concept/{basics => lasagna}/lasagna_test.rb | 0 9 files changed, 5 insertions(+), 1 deletion(-) rename exercises/concept/{basics => lasagna}/.docs/after.md (100%) rename exercises/concept/{basics => lasagna}/.docs/hints.md (100%) rename exercises/concept/{basics => lasagna}/.docs/instructions.md (100%) rename exercises/concept/{basics => lasagna}/.docs/introduction.md (100%) rename exercises/concept/{basics => lasagna}/.meta/config.json (65%) rename exercises/concept/{basics => lasagna}/.meta/design.md (100%) rename exercises/concept/{basics => lasagna}/.meta/example.rb (100%) rename exercises/concept/{basics => lasagna}/lasagna.rb (100%) rename exercises/concept/{basics => lasagna}/lasagna_test.rb (100%) diff --git a/exercises/concept/basics/.docs/after.md b/exercises/concept/lasagna/.docs/after.md similarity index 100% rename from exercises/concept/basics/.docs/after.md rename to exercises/concept/lasagna/.docs/after.md diff --git a/exercises/concept/basics/.docs/hints.md b/exercises/concept/lasagna/.docs/hints.md similarity index 100% rename from exercises/concept/basics/.docs/hints.md rename to exercises/concept/lasagna/.docs/hints.md diff --git a/exercises/concept/basics/.docs/instructions.md b/exercises/concept/lasagna/.docs/instructions.md similarity index 100% rename from exercises/concept/basics/.docs/instructions.md rename to exercises/concept/lasagna/.docs/instructions.md diff --git a/exercises/concept/basics/.docs/introduction.md b/exercises/concept/lasagna/.docs/introduction.md similarity index 100% rename from exercises/concept/basics/.docs/introduction.md rename to exercises/concept/lasagna/.docs/introduction.md diff --git a/exercises/concept/basics/.meta/config.json b/exercises/concept/lasagna/.meta/config.json similarity index 65% rename from exercises/concept/basics/.meta/config.json rename to exercises/concept/lasagna/.meta/config.json index 3ee737416f..5b9e1717dc 100644 --- a/exercises/concept/basics/.meta/config.json +++ b/exercises/concept/lasagna/.meta/config.json @@ -8,5 +8,9 @@ "github_username": "pvcarrera", "exercism_username": "pvcarrera" } - ] + ], + "editor": { + "solution_files": ["lasagna.rb"], + "test_files": ["lasagna_test.rb"] + } } diff --git a/exercises/concept/basics/.meta/design.md b/exercises/concept/lasagna/.meta/design.md similarity index 100% rename from exercises/concept/basics/.meta/design.md rename to exercises/concept/lasagna/.meta/design.md diff --git a/exercises/concept/basics/.meta/example.rb b/exercises/concept/lasagna/.meta/example.rb similarity index 100% rename from exercises/concept/basics/.meta/example.rb rename to exercises/concept/lasagna/.meta/example.rb diff --git a/exercises/concept/basics/lasagna.rb b/exercises/concept/lasagna/lasagna.rb similarity index 100% rename from exercises/concept/basics/lasagna.rb rename to exercises/concept/lasagna/lasagna.rb diff --git a/exercises/concept/basics/lasagna_test.rb b/exercises/concept/lasagna/lasagna_test.rb similarity index 100% rename from exercises/concept/basics/lasagna_test.rb rename to exercises/concept/lasagna/lasagna_test.rb From 90ac81311aa5cebcd88844de6e6b6463b1bb7860 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Sat, 10 Oct 2020 16:46:48 +0200 Subject: [PATCH 033/102] Create folder structure for exception concept --- exercises/concept/exceptions/.docs/after.md | 0 exercises/concept/exceptions/.docs/hints.md | 0 exercises/concept/exceptions/.docs/instructions.md | 0 exercises/concept/exceptions/.docs/introduction.md | 0 exercises/concept/exceptions/.meta/config.json | 0 exercises/concept/exceptions/.meta/design.md | 0 exercises/concept/exceptions/.meta/example.rb | 0 exercises/concept/exceptions/exceptions.rb | 0 exercises/concept/exceptions/exceptions_test.rb | 0 9 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 exercises/concept/exceptions/.docs/after.md create mode 100644 exercises/concept/exceptions/.docs/hints.md create mode 100644 exercises/concept/exceptions/.docs/instructions.md create mode 100644 exercises/concept/exceptions/.docs/introduction.md create mode 100644 exercises/concept/exceptions/.meta/config.json create mode 100644 exercises/concept/exceptions/.meta/design.md create mode 100644 exercises/concept/exceptions/.meta/example.rb create mode 100644 exercises/concept/exceptions/exceptions.rb create mode 100644 exercises/concept/exceptions/exceptions_test.rb diff --git a/exercises/concept/exceptions/.docs/after.md b/exercises/concept/exceptions/.docs/after.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exercises/concept/exceptions/.docs/hints.md b/exercises/concept/exceptions/.docs/hints.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exercises/concept/exceptions/.docs/instructions.md b/exercises/concept/exceptions/.docs/instructions.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exercises/concept/exceptions/.docs/introduction.md b/exercises/concept/exceptions/.docs/introduction.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exercises/concept/exceptions/.meta/config.json b/exercises/concept/exceptions/.meta/config.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exercises/concept/exceptions/.meta/design.md b/exercises/concept/exceptions/.meta/design.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exercises/concept/exceptions/.meta/example.rb b/exercises/concept/exceptions/.meta/example.rb new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exercises/concept/exceptions/exceptions.rb b/exercises/concept/exceptions/exceptions.rb new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exercises/concept/exceptions/exceptions_test.rb b/exercises/concept/exceptions/exceptions_test.rb new file mode 100644 index 0000000000..e69de29bb2 From 56a82a7c93716b4ef29c6b376528ccb277ca2b1f Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Sat, 10 Oct 2020 20:46:38 +0200 Subject: [PATCH 034/102] Add tests and example --- exercises/concept/exceptions/.meta/example.rb | 16 +++++++ exercises/concept/exceptions/exceptions.rb | 0 .../concept/exceptions/exceptions_test.rb | 0 .../concept/exceptions/simple_calculator.rb | 12 ++++++ .../exceptions/simple_calculator_test.rb | 42 +++++++++++++++++++ 5 files changed, 70 insertions(+) delete mode 100644 exercises/concept/exceptions/exceptions.rb delete mode 100644 exercises/concept/exceptions/exceptions_test.rb create mode 100644 exercises/concept/exceptions/simple_calculator.rb create mode 100644 exercises/concept/exceptions/simple_calculator_test.rb diff --git a/exercises/concept/exceptions/.meta/example.rb b/exercises/concept/exceptions/.meta/example.rb index e69de29bb2..dd9d66f72e 100644 --- a/exercises/concept/exceptions/.meta/example.rb +++ b/exercises/concept/exceptions/.meta/example.rb @@ -0,0 +1,16 @@ +class SimpleCalculator + ALLOWED_OPERATIONS = ['+', '-', '/', '*'] + + UnsupportedOperation = Class.new(StandardError) + + def self.calculate(first_operand, second_operand, operation) + raise ArgumentError.new unless (first_operand.is_a?(Integer) && second_operand.is_a?(Integer)) + raise UnsupportedOperation.new unless ALLOWED_OPERATIONS.include?(operation) + + result = first_operand.to_i.public_send(operation, second_operand.to_i) + + "#{first_operand} #{operation} #{second_operand} = #{result}" + rescue ZeroDivisionError + 'Division by zero is not allowed.' + end +end diff --git a/exercises/concept/exceptions/exceptions.rb b/exercises/concept/exceptions/exceptions.rb deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/exercises/concept/exceptions/exceptions_test.rb b/exercises/concept/exceptions/exceptions_test.rb deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/exercises/concept/exceptions/simple_calculator.rb b/exercises/concept/exceptions/simple_calculator.rb new file mode 100644 index 0000000000..a703f8fef4 --- /dev/null +++ b/exercises/concept/exceptions/simple_calculator.rb @@ -0,0 +1,12 @@ +class SimpleCalculator + ALLOWED_OPERATIONS = ['+', '-', '/', '*'] + + # TODO: Show how to define custom exceptions + # TODO: Explain why custom errors are subclasses of StandardError + # TODO: Explain why is not a good idea to rescue from Exception + UnsupportedOperation = Class.new(StandardError) + + def self.calculate(first_operand, second_operand, operation) + raise NotImplementedError, 'Please implement the SimpleCalculator.calculate method' + end +end diff --git a/exercises/concept/exceptions/simple_calculator_test.rb b/exercises/concept/exceptions/simple_calculator_test.rb new file mode 100644 index 0000000000..63b51673dc --- /dev/null +++ b/exercises/concept/exceptions/simple_calculator_test.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'minitest/autorun' +require_relative 'simple_calculator' + +class SimpleCalculatorTest < Minitest::Test + def test_addition_with + assert_equal '22 + 25 = 47', SimpleCalculator.calculate(22, 25, '+') + end + + def test_multiplication + assert_equal '3 * 21 = 63', SimpleCalculator.calculate(3, 21, '*') + end + + def test_division + assert_equal '72 / 9 = 8', SimpleCalculator.calculate(72, 9, '/') + end + + def test_rescues_division_by_0_exception + assert_equal "Division by zero is not allowed.", SimpleCalculator.calculate(33, 0, "/") + end + + def test_no_number_first_operand_raises_exception + assert_raises(ArgumentError) { SimpleCalculator.calculate('1', 2, '+') } + end + + def test_no_number_second_operand_raises_exception + assert_raises(ArgumentError) { SimpleCalculator.calculate(1, '2', '+') } + end + + def test_raises_exception_for_non_valid_operations + assert_raises(SimpleCalculator::UnsupportedOperation) { SimpleCalculator.calculate(1, 2, '**') } + end + + def test_raises_exception_when_operation_is_nil + assert_raises(SimpleCalculator::UnsupportedOperation) { SimpleCalculator.calculate(1, 2, nil) } + end + + def test_raises_exception_when_operation_is_an_empty_string + assert_raises(SimpleCalculator::UnsupportedOperation) { SimpleCalculator.calculate(1, 2, '') } + end +end From 970eb75d92a365298efdcf8928c599f916c55f5e Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Sun, 11 Oct 2020 12:46:55 +0200 Subject: [PATCH 035/102] Add instructions --- .../concept/exceptions/.docs/instructions.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/exercises/concept/exceptions/.docs/instructions.md b/exercises/concept/exceptions/.docs/instructions.md index e69de29bb2..ebe2430bf6 100644 --- a/exercises/concept/exceptions/.docs/instructions.md +++ b/exercises/concept/exceptions/.docs/instructions.md @@ -0,0 +1,33 @@ +In this exercise you will be building error handling for a simple integer calculator. + +The goal is to have a working calculator that returns a string with the following pattern: `16 + 51 = 67`, when provided with arguments `16`, `51` and `+`. + +```ruby +SimpleCalculator.calculate(16, 51, "+"); // => returns "16 + 51 = 67" +SimpleCalculator.calculate(32, 6, "*"); // => returns "32 * 6 = 192" +SimpleCalculator.calculate(512, 4, "/"); // => returns "512 / 4 = 128" +``` + +## 1. Handle the code that may raise errors within the method `calculate` + +The main method for implementation in this task will be the class method `SimpleCalculator.calculate()` method. It takes three arguments. The first two arguments are integer numbers on which an operation is going to be conducted. The third argument is of type string and for this exercise it is necessary to implement the following operations: + +- addition using the `+` string +- multiplication using the `*` string +- division using the `/` string + +## 2. Handle illegal operations + +Any other operation symbol should raise the `UnsupportedOperation` exception. + +```ruby +SimpleCalculator.calculate(1, '2', '+'); // => Raises an ArgumentError +``` + +## 4. Handle DivideByZero exceptions + +When a `ZeroDivisionError` exception gets raise, the handling code should return the string with the content `Division by zero is not allowed.`. Any other exception should not be handled by the `SimpleCalculator.calculate()` method. + +```ruby +SimpleCalculator.calculate(512, 0, "/"); // => returns "Division by zero is not allowed." +``` From 51ab145f9fc7ec5daa86c9bb04aa9561bc6b3829 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Mon, 12 Oct 2020 19:34:21 +0200 Subject: [PATCH 036/102] Remove Integer limitations --- exercises/concept/exceptions/.docs/instructions.md | 4 ++-- exercises/concept/exceptions/.meta/example.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exercises/concept/exceptions/.docs/instructions.md b/exercises/concept/exceptions/.docs/instructions.md index ebe2430bf6..ab9c82f861 100644 --- a/exercises/concept/exceptions/.docs/instructions.md +++ b/exercises/concept/exceptions/.docs/instructions.md @@ -1,4 +1,4 @@ -In this exercise you will be building error handling for a simple integer calculator. +In this exercise you will be building error handling for a simple calculator. The goal is to have a working calculator that returns a string with the following pattern: `16 + 51 = 67`, when provided with arguments `16`, `51` and `+`. @@ -10,7 +10,7 @@ SimpleCalculator.calculate(512, 4, "/"); // => returns "512 / 4 = 128" ## 1. Handle the code that may raise errors within the method `calculate` -The main method for implementation in this task will be the class method `SimpleCalculator.calculate()` method. It takes three arguments. The first two arguments are integer numbers on which an operation is going to be conducted. The third argument is of type string and for this exercise it is necessary to implement the following operations: +The main method for implementation in this task will be the class method `SimpleCalculator.calculate()` method. It takes three arguments. The first two arguments are numbers on which an operation is going to be conducted. The third argument is of type string and for this exercise it is necessary to implement the following operations: - addition using the `+` string - multiplication using the `*` string diff --git a/exercises/concept/exceptions/.meta/example.rb b/exercises/concept/exceptions/.meta/example.rb index dd9d66f72e..2bdbf25964 100644 --- a/exercises/concept/exceptions/.meta/example.rb +++ b/exercises/concept/exceptions/.meta/example.rb @@ -4,10 +4,10 @@ class SimpleCalculator UnsupportedOperation = Class.new(StandardError) def self.calculate(first_operand, second_operand, operation) - raise ArgumentError.new unless (first_operand.is_a?(Integer) && second_operand.is_a?(Integer)) + raise ArgumentError.new unless (first_operand.is_a?(Number) && second_operand.is_a?(Number)) raise UnsupportedOperation.new unless ALLOWED_OPERATIONS.include?(operation) - result = first_operand.to_i.public_send(operation, second_operand.to_i) + result = first_operand.public_send(operation, second_operand) "#{first_operand} #{operation} #{second_operand} = #{result}" rescue ZeroDivisionError From 8a9bf257ce8b68ea1db9c3da2285f3b129576650 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Mon, 12 Oct 2020 19:35:24 +0200 Subject: [PATCH 037/102] Remove frozen_strings_literals --- exercises/concept/exceptions/simple_calculator_test.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/exercises/concept/exceptions/simple_calculator_test.rb b/exercises/concept/exceptions/simple_calculator_test.rb index 63b51673dc..1b26e42796 100644 --- a/exercises/concept/exceptions/simple_calculator_test.rb +++ b/exercises/concept/exceptions/simple_calculator_test.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - require 'minitest/autorun' require_relative 'simple_calculator' From 7ec28e054794b5840f020b3f98c1131f96fce3c7 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Mon, 12 Oct 2020 20:59:17 +0200 Subject: [PATCH 038/102] Start design.md --- exercises/concept/exceptions/.meta/design.md | 36 ++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/exercises/concept/exceptions/.meta/design.md b/exercises/concept/exceptions/.meta/design.md index e69de29bb2..1d7378e35a 100644 --- a/exercises/concept/exceptions/.meta/design.md +++ b/exercises/concept/exceptions/.meta/design.md @@ -0,0 +1,36 @@ +## Goal + +The goal of this exercise is to teach the student the Concept of Exceptions in Ruby. + +## Learning objectives + +- Know what exceptions are. +- Know when an exception should be raised. +- Know how to raised an exception. +- Know how to rescue an when to re-raise an exception. +- Know the most important built-in exceptions (`Error`, `StandardError`, `ArgumentError`). +- Know how to create custom exceptions. + +## Out of scope + +- Memory and performance characteristics. + +## Concepts + +- `exceptions`: know what exceptions are; know when an exception should be raised; know how to raised an exception; know how to rescue an when to re-raise an exception; know the most important built-in exceptions (`Error`, `StandardError`, `ArgumentError`); know how to create custom exceptions + +## Prequisites + +- `basics`: know how to do string interpolation and how to work with `int`s +- `inheritance`: know about class hierarchies +- `nullability`: know what `nil` is + +## Resources to refer to + +### Hints + +TODO: Find nice online documentation to link here + +### After + +TODO: Find nice online documentation to link here From d27b8ab9bf30cc6e6866e0a4b7aaad8085064e50 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Tue, 13 Oct 2020 21:12:57 +0200 Subject: [PATCH 039/102] Add links to the pragmatic programer exceptions chapter --- exercises/concept/exceptions/.meta/design.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/exercises/concept/exceptions/.meta/design.md b/exercises/concept/exceptions/.meta/design.md index 1d7378e35a..b6dd82efd7 100644 --- a/exercises/concept/exceptions/.meta/design.md +++ b/exercises/concept/exceptions/.meta/design.md @@ -29,8 +29,10 @@ The goal of this exercise is to teach the student the Concept of Exceptions in R ### Hints -TODO: Find nice online documentation to link here +- [Exceptions in Ruby][exceptions]: The Pragmatic Programmer's Guide. Exceptions chapter. ### After -TODO: Find nice online documentation to link here +- [Exceptions in Ruby][exceptions]: The Pragmatic Programmer's Guide. Exceptions chapter. + +[exceptions]: https://ruby-doc.com/docs/ProgrammingRuby/html/tut_exceptions.html From 732dcc2b3edd20881fe6a727c78b79d6fa507925 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Tue, 13 Oct 2020 21:17:02 +0200 Subject: [PATCH 040/102] Add config --- exercises/concept/exceptions/.meta/config.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/exercises/concept/exceptions/.meta/config.json b/exercises/concept/exceptions/.meta/config.json index e69de29bb2..1d9a6cd3f7 100644 --- a/exercises/concept/exceptions/.meta/config.json +++ b/exercises/concept/exceptions/.meta/config.json @@ -0,0 +1,9 @@ +{ + "authors": [ + { + "github_username": "pvcarrera", + "exercism_username": "pvcarrera" + } + ], + "forked_from": ["csharp/exceptions"] +} From 7b8436e99ded91ce5dbb954d0a9497169bd8bd0e Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Wed, 14 Oct 2020 21:26:24 +0200 Subject: [PATCH 041/102] Add introduction --- .../concept/exceptions/.docs/introduction.md | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/exercises/concept/exceptions/.docs/introduction.md b/exercises/concept/exceptions/.docs/introduction.md index e69de29bb2..ca857364c5 100644 --- a/exercises/concept/exceptions/.docs/introduction.md +++ b/exercises/concept/exceptions/.docs/introduction.md @@ -0,0 +1,73 @@ +Exceptions in Ruby as in most languages provide a way of dealing with unexpected events. Proper handling of exceptions is important when trying to prevent your program from crashing. + +When an exception is raised in your code, either by raising it explicitly or by Ruby interpreter raising it itself. The program stops and eventually exit with an error message: + +```ruby +raise ArgumentError.new("Something went wrong!") +=> Traceback (most recent call last): +. +. +ArgumentError (Something went wrong!) +``` + +```ruby +1/0 +=> Traceback (most recent call last): +. +. +ZeroDivisionError (divided by 0) +``` + +In case we want to stop this shut down process we need to react to the error. This is called "rescuing" and exception: + +```ruby +begin + # ...any code that raises an exception +rescue + puts 'Got an exception' +end +``` + +This program will not crash and it'll output "Got an exception". Instead of exiting, Ruby runs the code in the rescue block, which prints out a message. + +As everything in Ruby, exceptions are also objects and they usually hold data about the exception. This is how we can get the exception object: + +```ruby +begin + # ...any code that raises an exception +rescue => e + puts "Exception class: #{ e.class.name }" + puts"Exception Message:#{e.message}" +end +``` + +In Ruby it's also possible to raise your own exceptions. For example: + +```ruby +begin + raise ArgumentError.new("Invalid argument") +rescue ArgumentError => e + puts e.message +end +``` + +The previous exception is one of the [Ruby's built in exceptions][ruby-exceptions] but it's also possible to define custom exceptions and raise them: + +```ruby + +class CustomError < StandardError +end + +raise CustomError.new() + +``` + +```ruby +UnsupportedOperation = Class.new(StandardError) + +raise UnsupportedOperation.new() +end + + +[ruby-exceptions]: https://www.honeybadger.io/blog/understanding-the-ruby-exception-hierarchy +``` From 71b4b9bd8bd764eedffc4ffacb48d42aca964d3b Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Thu, 15 Oct 2020 09:03:26 +0200 Subject: [PATCH 042/102] Update languages/exercises/concept/exceptions/.docs/instructions.md Co-authored-by: Victor Goff --- exercises/concept/exceptions/.docs/instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/exceptions/.docs/instructions.md b/exercises/concept/exceptions/.docs/instructions.md index ab9c82f861..9b43bb01b6 100644 --- a/exercises/concept/exceptions/.docs/instructions.md +++ b/exercises/concept/exceptions/.docs/instructions.md @@ -26,7 +26,7 @@ SimpleCalculator.calculate(1, '2', '+'); // => Raises an ArgumentError ## 4. Handle DivideByZero exceptions -When a `ZeroDivisionError` exception gets raise, the handling code should return the string with the content `Division by zero is not allowed.`. Any other exception should not be handled by the `SimpleCalculator.calculate()` method. +When a `ZeroDivisionError` exception is raised, the handling code should return the string with the content `Division by zero is not allowed.`. Any other exception should not be handled by the `SimpleCalculator.calculate()` method. ```ruby SimpleCalculator.calculate(512, 0, "/"); // => returns "Division by zero is not allowed." From b3a29c28a2e6e977d2025609bd56ce79a19a58f2 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Thu, 15 Oct 2020 09:03:58 +0200 Subject: [PATCH 043/102] Update languages/exercises/concept/exceptions/.docs/instructions.md Co-authored-by: Victor Goff --- exercises/concept/exceptions/.docs/instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/exceptions/.docs/instructions.md b/exercises/concept/exceptions/.docs/instructions.md index 9b43bb01b6..072e368621 100644 --- a/exercises/concept/exceptions/.docs/instructions.md +++ b/exercises/concept/exceptions/.docs/instructions.md @@ -29,5 +29,5 @@ SimpleCalculator.calculate(1, '2', '+'); // => Raises an ArgumentError When a `ZeroDivisionError` exception is raised, the handling code should return the string with the content `Division by zero is not allowed.`. Any other exception should not be handled by the `SimpleCalculator.calculate()` method. ```ruby -SimpleCalculator.calculate(512, 0, "/"); // => returns "Division by zero is not allowed." +SimpleCalculator.calculate(512, 0, "/"); # => returns "Division by zero is not allowed." ``` From dd54d64cdc9548fbad5bc41546ec3edc27d57803 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Thu, 15 Oct 2020 09:04:23 +0200 Subject: [PATCH 044/102] Update languages/exercises/concept/exceptions/.docs/introduction.md Co-authored-by: Victor Goff --- exercises/concept/exceptions/.docs/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/exceptions/.docs/introduction.md b/exercises/concept/exceptions/.docs/introduction.md index ca857364c5..51431b5b0c 100644 --- a/exercises/concept/exceptions/.docs/introduction.md +++ b/exercises/concept/exceptions/.docs/introduction.md @@ -1,4 +1,4 @@ -Exceptions in Ruby as in most languages provide a way of dealing with unexpected events. Proper handling of exceptions is important when trying to prevent your program from crashing. +Exceptions in Ruby, as in many languages, provide a way of dealing with unexpected events. Proper handling of exceptions is important when trying to prevent your program from crashing. When an exception is raised in your code, either by raising it explicitly or by Ruby interpreter raising it itself. The program stops and eventually exit with an error message: From a9eb45ee87499b435a6a74dce7f9e14085e607a3 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Thu, 15 Oct 2020 09:04:54 +0200 Subject: [PATCH 045/102] Update languages/exercises/concept/exceptions/.docs/introduction.md Co-authored-by: Victor Goff --- exercises/concept/exceptions/.docs/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/exceptions/.docs/introduction.md b/exercises/concept/exceptions/.docs/introduction.md index 51431b5b0c..db31982929 100644 --- a/exercises/concept/exceptions/.docs/introduction.md +++ b/exercises/concept/exceptions/.docs/introduction.md @@ -1,6 +1,6 @@ Exceptions in Ruby, as in many languages, provide a way of dealing with unexpected events. Proper handling of exceptions is important when trying to prevent your program from crashing. -When an exception is raised in your code, either by raising it explicitly or by Ruby interpreter raising it itself. The program stops and eventually exit with an error message: +When an exception is raised, either by raising it explicitly or by the Ruby interpreter raising it, the program diverts normal operation and eventually exits with an error message: ```ruby raise ArgumentError.new("Something went wrong!") From 8dcdfbb6f8350db101d86e733a556ec0af839671 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Thu, 15 Oct 2020 09:05:14 +0200 Subject: [PATCH 046/102] Update languages/exercises/concept/exceptions/.docs/introduction.md Co-authored-by: Victor Goff --- exercises/concept/exceptions/.docs/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/exceptions/.docs/introduction.md b/exercises/concept/exceptions/.docs/introduction.md index db31982929..ef2d033558 100644 --- a/exercises/concept/exceptions/.docs/introduction.md +++ b/exercises/concept/exceptions/.docs/introduction.md @@ -18,7 +18,7 @@ ArgumentError (Something went wrong!) ZeroDivisionError (divided by 0) ``` -In case we want to stop this shut down process we need to react to the error. This is called "rescuing" and exception: +In case we want to stop this shut down process we need to react to the exception. This is called "rescuing" an exception: ```ruby begin From e5f2bd536f97386ef8110c85e590c98741f51800 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Thu, 15 Oct 2020 09:05:27 +0200 Subject: [PATCH 047/102] Update languages/exercises/concept/exceptions/.docs/introduction.md Co-authored-by: Victor Goff --- exercises/concept/exceptions/.docs/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/exceptions/.docs/introduction.md b/exercises/concept/exceptions/.docs/introduction.md index ef2d033558..ff713f5561 100644 --- a/exercises/concept/exceptions/.docs/introduction.md +++ b/exercises/concept/exceptions/.docs/introduction.md @@ -37,7 +37,7 @@ begin # ...any code that raises an exception rescue => e puts "Exception class: #{ e.class.name }" - puts"Exception Message:#{e.message}" + puts "Exception Message:#{e.message}" end ``` From 0fe3959999dbfae58e9a61309eb02715299977f9 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Thu, 15 Oct 2020 09:05:56 +0200 Subject: [PATCH 048/102] Update languages/exercises/concept/exceptions/.docs/introduction.md Co-authored-by: Victor Goff --- exercises/concept/exceptions/.docs/introduction.md | 1 - 1 file changed, 1 deletion(-) diff --git a/exercises/concept/exceptions/.docs/introduction.md b/exercises/concept/exceptions/.docs/introduction.md index ff713f5561..ad933db4bf 100644 --- a/exercises/concept/exceptions/.docs/introduction.md +++ b/exercises/concept/exceptions/.docs/introduction.md @@ -54,7 +54,6 @@ end The previous exception is one of the [Ruby's built in exceptions][ruby-exceptions] but it's also possible to define custom exceptions and raise them: ```ruby - class CustomError < StandardError end From e14fef1b811fdb7d80e13700d2570e72121c5550 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Thu, 15 Oct 2020 09:06:05 +0200 Subject: [PATCH 049/102] Update languages/exercises/concept/exceptions/.docs/introduction.md Co-authored-by: Victor Goff --- exercises/concept/exceptions/.docs/introduction.md | 1 - 1 file changed, 1 deletion(-) diff --git a/exercises/concept/exceptions/.docs/introduction.md b/exercises/concept/exceptions/.docs/introduction.md index ad933db4bf..acb663a184 100644 --- a/exercises/concept/exceptions/.docs/introduction.md +++ b/exercises/concept/exceptions/.docs/introduction.md @@ -58,7 +58,6 @@ class CustomError < StandardError end raise CustomError.new() - ``` ```ruby From 4d50f0a01ecb366f7dda90d7d0a51a3e5ac9097d Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Thu, 15 Oct 2020 09:08:27 +0200 Subject: [PATCH 050/102] Fix typo --- exercises/concept/exceptions/.docs/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/exceptions/.docs/introduction.md b/exercises/concept/exceptions/.docs/introduction.md index acb663a184..45a1585d96 100644 --- a/exercises/concept/exceptions/.docs/introduction.md +++ b/exercises/concept/exceptions/.docs/introduction.md @@ -65,7 +65,7 @@ UnsupportedOperation = Class.new(StandardError) raise UnsupportedOperation.new() end +``` [ruby-exceptions]: https://www.honeybadger.io/blog/understanding-the-ruby-exception-hierarchy -``` From ba11f99ded1d98d16cb545920d49091593d8b010 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Thu, 15 Oct 2020 09:10:57 +0200 Subject: [PATCH 051/102] Remove extra line --- exercises/concept/exceptions/.docs/introduction.md | 1 - 1 file changed, 1 deletion(-) diff --git a/exercises/concept/exceptions/.docs/introduction.md b/exercises/concept/exceptions/.docs/introduction.md index 45a1585d96..12bd4fc9de 100644 --- a/exercises/concept/exceptions/.docs/introduction.md +++ b/exercises/concept/exceptions/.docs/introduction.md @@ -67,5 +67,4 @@ raise UnsupportedOperation.new() end ``` - [ruby-exceptions]: https://www.honeybadger.io/blog/understanding-the-ruby-exception-hierarchy From 72ec53bac12204fe7b4ff5cba862c76c387727dd Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Fri, 16 Oct 2020 20:06:30 +0200 Subject: [PATCH 052/102] Remove link --- exercises/concept/exceptions/.docs/introduction.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/exercises/concept/exceptions/.docs/introduction.md b/exercises/concept/exceptions/.docs/introduction.md index 12bd4fc9de..15602ff227 100644 --- a/exercises/concept/exceptions/.docs/introduction.md +++ b/exercises/concept/exceptions/.docs/introduction.md @@ -51,7 +51,7 @@ rescue ArgumentError => e end ``` -The previous exception is one of the [Ruby's built in exceptions][ruby-exceptions] but it's also possible to define custom exceptions and raise them: +The previous exception is one of the Ruby's built in exceptions but it's also possible to define custom exceptions and raise them: ```ruby class CustomError < StandardError @@ -67,4 +67,3 @@ raise UnsupportedOperation.new() end ``` -[ruby-exceptions]: https://www.honeybadger.io/blog/understanding-the-ruby-exception-hierarchy From ef5d416050568838600377a6b3f40e91f8238d0d Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Fri, 16 Oct 2020 20:07:04 +0200 Subject: [PATCH 053/102] Add extended custom error --- .../concept/exceptions/.docs/introduction.md | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/exercises/concept/exceptions/.docs/introduction.md b/exercises/concept/exceptions/.docs/introduction.md index 15602ff227..492c9e2733 100644 --- a/exercises/concept/exceptions/.docs/introduction.md +++ b/exercises/concept/exceptions/.docs/introduction.md @@ -57,13 +57,30 @@ The previous exception is one of the Ruby's built in exceptions but it's also po class CustomError < StandardError end -raise CustomError.new() +raise CustomError.new("Something went wrong") ``` ```ruby UnsupportedOperation = Class.new(StandardError) -raise UnsupportedOperation.new() +raise UnsupportedOperation.new("Something went wrong") end ``` +These custom errors are subclasses of the `StandardError` class. Because custom errors are also a class, it's possible to add methods to it like in any other class. + +```ruby +class CustomError < StandardError + attr_reader :action + + def initialize(message, action) + # Call the parent's constructor to set the message + super(message) + + @action = action + end +end + +raise CustomError.new("Something went wrong", :send_notification) +``` + From 0fb288cb1680a008959538527b946d6f99438763 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Fri, 16 Oct 2020 20:07:51 +0200 Subject: [PATCH 054/102] Update languages/exercises/concept/exceptions/.docs/instructions.md Co-authored-by: Erik Schierboom --- exercises/concept/exceptions/.docs/instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/exceptions/.docs/instructions.md b/exercises/concept/exceptions/.docs/instructions.md index 072e368621..9efe8c7eb8 100644 --- a/exercises/concept/exceptions/.docs/instructions.md +++ b/exercises/concept/exceptions/.docs/instructions.md @@ -21,7 +21,7 @@ The main method for implementation in this task will be the class method `Simple Any other operation symbol should raise the `UnsupportedOperation` exception. ```ruby -SimpleCalculator.calculate(1, '2', '+'); // => Raises an ArgumentError +SimpleCalculator.calculate(1, '2', '-'); // => Raises an UnsupportedOperation ``` ## 4. Handle DivideByZero exceptions From c6a535e08f342210592ffaaeaf90fff4100d2bac Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Fri, 16 Oct 2020 20:10:00 +0200 Subject: [PATCH 055/102] Update languages/exercises/concept/exceptions/.docs/instructions.md Co-authored-by: Erik Schierboom --- exercises/concept/exceptions/.docs/instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/exceptions/.docs/instructions.md b/exercises/concept/exceptions/.docs/instructions.md index 9efe8c7eb8..2b75165dd4 100644 --- a/exercises/concept/exceptions/.docs/instructions.md +++ b/exercises/concept/exceptions/.docs/instructions.md @@ -18,7 +18,7 @@ The main method for implementation in this task will be the class method `Simple ## 2. Handle illegal operations -Any other operation symbol should raise the `UnsupportedOperation` exception. +Update the `SimpleCalculator.calculate()` method to raise an `UnsupportedOperation` exception for unknown operation symbols. ```ruby SimpleCalculator.calculate(1, '2', '-'); // => Raises an UnsupportedOperation From 5d60474004fa924adfe660786d4865e259e7e13c Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Fri, 16 Oct 2020 20:15:28 +0200 Subject: [PATCH 056/102] Rephrase intro step 4 --- exercises/concept/exceptions/.docs/instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/exceptions/.docs/instructions.md b/exercises/concept/exceptions/.docs/instructions.md index 2b75165dd4..318bc0db90 100644 --- a/exercises/concept/exceptions/.docs/instructions.md +++ b/exercises/concept/exceptions/.docs/instructions.md @@ -26,7 +26,7 @@ SimpleCalculator.calculate(1, '2', '-'); // => Raises an UnsupportedOperation ## 4. Handle DivideByZero exceptions -When a `ZeroDivisionError` exception is raised, the handling code should return the string with the content `Division by zero is not allowed.`. Any other exception should not be handled by the `SimpleCalculator.calculate()` method. +Update the `SimpleCalculator.calculate()` to handle `ZeroDivisionError` exceptions. The handling code should return the string with the content `Division by zero is not allowed.`. Any other exception should not be handled by the `SimpleCalculator.calculate()` method. ```ruby SimpleCalculator.calculate(512, 0, "/"); # => returns "Division by zero is not allowed." From 5af68ca26fb30beef5be5a8d3af3d025a3544508 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Fri, 16 Oct 2020 20:20:08 +0200 Subject: [PATCH 057/102] Update TODOs --- exercises/concept/exceptions/.docs/after.md | 6 ++++++ exercises/concept/exceptions/simple_calculator.rb | 3 --- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/exercises/concept/exceptions/.docs/after.md b/exercises/concept/exceptions/.docs/after.md index e69de29bb2..2e16551baa 100644 --- a/exercises/concept/exceptions/.docs/after.md +++ b/exercises/concept/exceptions/.docs/after.md @@ -0,0 +1,6 @@ +# TODO: Show full rescue syntax +# TODO: Method rescue syntax +# TODO: Retry keyword +# TODO: Re-raising exceptions +# TODO: Rescuing from Exception +# TODO: Rescuing from StandardError diff --git a/exercises/concept/exceptions/simple_calculator.rb b/exercises/concept/exceptions/simple_calculator.rb index a703f8fef4..8096f42a8c 100644 --- a/exercises/concept/exceptions/simple_calculator.rb +++ b/exercises/concept/exceptions/simple_calculator.rb @@ -1,9 +1,6 @@ class SimpleCalculator ALLOWED_OPERATIONS = ['+', '-', '/', '*'] - # TODO: Show how to define custom exceptions - # TODO: Explain why custom errors are subclasses of StandardError - # TODO: Explain why is not a good idea to rescue from Exception UnsupportedOperation = Class.new(StandardError) def self.calculate(first_operand, second_operand, operation) From 9468c04897b6d71dc0e40df291d4314bf3cbe4b5 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Fri, 16 Oct 2020 20:20:21 +0200 Subject: [PATCH 058/102] Remove unsupported operation --- exercises/concept/exceptions/.meta/example.rb | 2 +- exercises/concept/exceptions/simple_calculator.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/concept/exceptions/.meta/example.rb b/exercises/concept/exceptions/.meta/example.rb index 2bdbf25964..b7c724fe39 100644 --- a/exercises/concept/exceptions/.meta/example.rb +++ b/exercises/concept/exceptions/.meta/example.rb @@ -1,5 +1,5 @@ class SimpleCalculator - ALLOWED_OPERATIONS = ['+', '-', '/', '*'] + ALLOWED_OPERATIONS = ['+', '/', '*'] UnsupportedOperation = Class.new(StandardError) diff --git a/exercises/concept/exceptions/simple_calculator.rb b/exercises/concept/exceptions/simple_calculator.rb index 8096f42a8c..edfd5a6549 100644 --- a/exercises/concept/exceptions/simple_calculator.rb +++ b/exercises/concept/exceptions/simple_calculator.rb @@ -1,5 +1,5 @@ class SimpleCalculator - ALLOWED_OPERATIONS = ['+', '-', '/', '*'] + ALLOWED_OPERATIONS = ['+', '/', '*'] UnsupportedOperation = Class.new(StandardError) From d95531b724e4c0cefeb97fc2b5af14ab2ae2faf3 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Fri, 16 Oct 2020 20:21:32 +0200 Subject: [PATCH 059/102] Remove custom error from stub --- exercises/concept/exceptions/simple_calculator.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/exercises/concept/exceptions/simple_calculator.rb b/exercises/concept/exceptions/simple_calculator.rb index edfd5a6549..19e98f51bd 100644 --- a/exercises/concept/exceptions/simple_calculator.rb +++ b/exercises/concept/exceptions/simple_calculator.rb @@ -1,8 +1,6 @@ class SimpleCalculator ALLOWED_OPERATIONS = ['+', '/', '*'] - UnsupportedOperation = Class.new(StandardError) - def self.calculate(first_operand, second_operand, operation) raise NotImplementedError, 'Please implement the SimpleCalculator.calculate method' end From 0ec023aacca14e0ad6951c4125e8b577ffd552cd Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Fri, 16 Oct 2020 20:29:39 +0200 Subject: [PATCH 060/102] Remove custom exception alternative syntax --- exercises/concept/exceptions/.docs/introduction.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/exercises/concept/exceptions/.docs/introduction.md b/exercises/concept/exceptions/.docs/introduction.md index 492c9e2733..e825ff9d1e 100644 --- a/exercises/concept/exceptions/.docs/introduction.md +++ b/exercises/concept/exceptions/.docs/introduction.md @@ -60,13 +60,6 @@ end raise CustomError.new("Something went wrong") ``` -```ruby -UnsupportedOperation = Class.new(StandardError) - -raise UnsupportedOperation.new("Something went wrong") -end -``` - These custom errors are subclasses of the `StandardError` class. Because custom errors are also a class, it's possible to add methods to it like in any other class. ```ruby From 9ca3cb9558d73b46e504f25b1c934c7fd71ae8a2 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Fri, 16 Oct 2020 20:30:58 +0200 Subject: [PATCH 061/102] Fix format --- exercises/concept/exceptions/.docs/after.md | 5 +++++ exercises/concept/exceptions/.docs/introduction.md | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/exercises/concept/exceptions/.docs/after.md b/exercises/concept/exceptions/.docs/after.md index 2e16551baa..102ee78c93 100644 --- a/exercises/concept/exceptions/.docs/after.md +++ b/exercises/concept/exceptions/.docs/after.md @@ -1,6 +1,11 @@ # TODO: Show full rescue syntax + # TODO: Method rescue syntax + # TODO: Retry keyword + # TODO: Re-raising exceptions + # TODO: Rescuing from Exception + # TODO: Rescuing from StandardError diff --git a/exercises/concept/exceptions/.docs/introduction.md b/exercises/concept/exceptions/.docs/introduction.md index e825ff9d1e..9667240254 100644 --- a/exercises/concept/exceptions/.docs/introduction.md +++ b/exercises/concept/exceptions/.docs/introduction.md @@ -76,4 +76,3 @@ end raise CustomError.new("Something went wrong", :send_notification) ``` - From 350844bde3cb63d9198d9b28dcda498db25e622d Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Sat, 24 Oct 2020 11:58:12 +0200 Subject: [PATCH 062/102] Adjust to new specification --- .../exceptions/.docs/after.md => concepts/exceptions/about.md | 0 concepts/exceptions/links.json | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename exercises/concept/exceptions/.docs/after.md => concepts/exceptions/about.md (100%) create mode 100644 concepts/exceptions/links.json diff --git a/exercises/concept/exceptions/.docs/after.md b/concepts/exceptions/about.md similarity index 100% rename from exercises/concept/exceptions/.docs/after.md rename to concepts/exceptions/about.md diff --git a/concepts/exceptions/links.json b/concepts/exceptions/links.json new file mode 100644 index 0000000000..e69de29bb2 From baad19c731a5b56e762d7a1aa2da5e4f1194fb90 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Sat, 24 Oct 2020 12:06:22 +0200 Subject: [PATCH 063/102] Remove section from introduction --- .../concept/exceptions/.docs/introduction.md | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/exercises/concept/exceptions/.docs/introduction.md b/exercises/concept/exceptions/.docs/introduction.md index 9667240254..82e93186f4 100644 --- a/exercises/concept/exceptions/.docs/introduction.md +++ b/exercises/concept/exceptions/.docs/introduction.md @@ -59,20 +59,3 @@ end raise CustomError.new("Something went wrong") ``` - -These custom errors are subclasses of the `StandardError` class. Because custom errors are also a class, it's possible to add methods to it like in any other class. - -```ruby -class CustomError < StandardError - attr_reader :action - - def initialize(message, action) - # Call the parent's constructor to set the message - super(message) - - @action = action - end -end - -raise CustomError.new("Something went wrong", :send_notification) -``` From 0d88926711e66f9b8563b33bb3c7ae55a087e916 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Wed, 28 Oct 2020 19:31:37 +0100 Subject: [PATCH 064/102] Update languages/exercises/concept/exceptions/.meta/example.rb Co-authored-by: Derk-Jan Karrenbeld --- exercises/concept/exceptions/.meta/example.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/exceptions/.meta/example.rb b/exercises/concept/exceptions/.meta/example.rb index b7c724fe39..2fe9d5090f 100644 --- a/exercises/concept/exceptions/.meta/example.rb +++ b/exercises/concept/exceptions/.meta/example.rb @@ -4,7 +4,7 @@ class SimpleCalculator UnsupportedOperation = Class.new(StandardError) def self.calculate(first_operand, second_operand, operation) - raise ArgumentError.new unless (first_operand.is_a?(Number) && second_operand.is_a?(Number)) + raise ArgumentError unless (first_operand.is_a?(Number) && second_operand.is_a?(Number)) raise UnsupportedOperation.new unless ALLOWED_OPERATIONS.include?(operation) result = first_operand.public_send(operation, second_operand) From f7552a1c977dccd26441888161b8f9dc5364e119 Mon Sep 17 00:00:00 2001 From: Pablo Vicente Date: Wed, 28 Oct 2020 20:10:04 +0100 Subject: [PATCH 065/102] Add about.md --- concepts/exceptions/about.md | 67 ++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/concepts/exceptions/about.md b/concepts/exceptions/about.md index 102ee78c93..ceb3d04ce7 100644 --- a/concepts/exceptions/about.md +++ b/concepts/exceptions/about.md @@ -1,11 +1,66 @@ -# TODO: Show full rescue syntax +It is important to note that exceptions should be used in cases where something exceptional happens, an error that needs special handling. Exceptions should not be used for control-flow of a program, as that is considered bad design, which often leads to bad performance and maintainability. -# TODO: Method rescue syntax +In Ruby exceptions follow a class hierarchy where `Exception` is the base class. These are the most common Ruby's built-in exceptions: -# TODO: Retry keyword +``` +Exception + NoMemoryError + ScriptError + LoadError + NotImplementedError + SyntaxError + SignalException + Interrupt + StandardError + ArgumentError + IOError + EOFError + IndexError + LocalJumpError + NameError + NoMethodError + RangeError + FloatDomainError + RegexpError + RuntimeError + SecurityError + SystemCallError + SystemStackError + ThreadError + TypeError + ZeroDivisionError + SystemExit +``` -# TODO: Re-raising exceptions +Rescuing errors of a specific class also rescues errors of its children. This is why rescuing from `Exception` can be dangerous. +Ruby uses exceptions to also handle messages from the operative system "Signals", for example `ctrl-c`. This means that rescuing from `Exception` will also capture this system "Signals". So in order to prevent unexpected behaviours the common practice to capture "all errors" is to rescue form `StandardError`. -# TODO: Rescuing from Exception +Ruby also provide extended rescue clauses for situations that require an special treatment: -# TODO: Rescuing from StandardError +```ruby +begin +... +rescue CustomError => error + # This block is run if a CustomError occurs +rescue AnotherCustomError => error + # This block is run if a AnotherCustomError occurs +else + # This block is run if no exception occurred at all +ensure + # This block always run, regardless of whether an exception occurred +end +``` + +This can be useful for example when working with network IO where we always need to remember to close a connection. + +Ruby rescue blocks can also use the `retry` keyword which re-runs everything between begin and rescue: + +```ruby +counter = 0 +begin + counter += 1 + api_request +rescue + retry if counter <= 3 +end +``` From c474e7c1c3440c6732e8718674a9acf93897ab73 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Wed, 11 Nov 2020 15:03:25 +0100 Subject: [PATCH 066/102] Add description of concept documents [Docs] Add description of concept documents Co-authored-by: Jeremy Walker --- reference/implementing-a-concept-exercise.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/reference/implementing-a-concept-exercise.md b/reference/implementing-a-concept-exercise.md index 388775ef1d..5f4c71feca 100644 --- a/reference/implementing-a-concept-exercise.md +++ b/reference/implementing-a-concept-exercise.md @@ -12,7 +12,7 @@ Please also watch the following video: - [The Anatomy of a Concept Exercise][anatomy-of-a-concept-exercise]. -As this document is generic, `` will be use as the placeholder for the name of the exercise in underscore-case (e.g. `string_interpolation`) +As this document is generic, `` will be used as the placeholder for the name of the exercise in underscore-case (e.g. `calculator_conundrum`) and `` will be used as the placeholder for the name of a concept. Before implementing the exercise, please make sure you have a good understanding of what the exercise should be teaching (and what not). This information can be found in the exercise's GitHub issue. Having done this, please read the [Ruby concept exercises introduction][concept-exercises]. @@ -21,6 +21,10 @@ To implement a concept exercise, the following files must be added:
 languages
 └── ruby
+    ├── concepts
+    |   └── <CONCEPT>
+    |       ├── about.md
+    |       └── links.json
     └── exercises
         └── concept
             └── 
@@ -28,7 +32,6 @@ languages
                 |   ├── instructions.md
                 |   ├── introduction.md
                 |   ├── hints.md
-                |   ├── after.md
                 |   └── source.md (required if there are third-party sources)
                 ├── .meta
                 |   |── config.json

From 34dd44e12bc8174c64f0fec0991f8b65382e7df8 Mon Sep 17 00:00:00 2001
From: Erik Schierboom 
Date: Thu, 12 Nov 2020 08:26:09 +0100
Subject: [PATCH 067/102] Add concept headings to introduction.md

* Add concept headings to introduction.md

* Update languages/exercises/concept/numbers/.docs/introduction.md

Co-authored-by: Victor Goff 

* Update languages/exercises/concept/instance-variables/.docs/introduction.md

Co-authored-by: Victor Goff 

* Update languages/exercises/concept/floating-point-numbers/.docs/introduction.md

Co-authored-by: Victor Goff 

Co-authored-by: Victor Goff 
---
 exercises/concept/arrays/.docs/introduction.md                | 2 ++
 exercises/concept/booleans/.docs/introduction.md              | 2 ++
 .../concept/floating-point-numbers/.docs/introduction.md      | 4 ++++
 exercises/concept/instance-variables/.docs/introduction.md    | 4 ++++
 exercises/concept/lasagna/.docs/introduction.md               | 2 ++
 exercises/concept/numbers/.docs/introduction.md               | 4 ++++
 exercises/concept/strings/.docs/introduction.md               | 2 ++
 7 files changed, 20 insertions(+)

diff --git a/exercises/concept/arrays/.docs/introduction.md b/exercises/concept/arrays/.docs/introduction.md
index ac17cb6f6b..ecba904dd2 100644
--- a/exercises/concept/arrays/.docs/introduction.md
+++ b/exercises/concept/arrays/.docs/introduction.md
@@ -1,3 +1,5 @@
+## arrays
+
 In Ruby, **arrays** are ordered, integer-indexed collections of any object. Array indexing starts at `0`. A negative index is assumed to be relative to the end of the array — i.e. an index of `-1` indicates the last element of the array, `-2` is the next to last element in the array, and so on.
 Ruby arrays mix in the [Enumerable module][enumerable-module], which adds several traversal and searching methods, and with the ability to sort.
 
diff --git a/exercises/concept/booleans/.docs/introduction.md b/exercises/concept/booleans/.docs/introduction.md
index aef2c5f33d..98f7446ecc 100644
--- a/exercises/concept/booleans/.docs/introduction.md
+++ b/exercises/concept/booleans/.docs/introduction.md
@@ -1,3 +1,5 @@
+## booleans
+
 ## True and False
 
 True and false logical states are represented with `true` and `false` in Ruby. These may either be used as literals on their own, or as a result of logical or comparison methods.
diff --git a/exercises/concept/floating-point-numbers/.docs/introduction.md b/exercises/concept/floating-point-numbers/.docs/introduction.md
index 050095f094..a819fc438e 100644
--- a/exercises/concept/floating-point-numbers/.docs/introduction.md
+++ b/exercises/concept/floating-point-numbers/.docs/introduction.md
@@ -1,3 +1,7 @@
+## floating-point-numbers
+
+## loops
+
 A floating-point number is a number with zero or more digits behind the decimal separator. Examples are `4.0`, `0.1`, `3.14`, `-6.4` `16.984025` and `1024.0`.
 In Ruby, floating-point numbers are implemented through the [Float](https://ruby-doc.org/core-2.7.0/Float.html) class.
 
diff --git a/exercises/concept/instance-variables/.docs/introduction.md b/exercises/concept/instance-variables/.docs/introduction.md
index b77ec17029..e78383db49 100644
--- a/exercises/concept/instance-variables/.docs/introduction.md
+++ b/exercises/concept/instance-variables/.docs/introduction.md
@@ -1,3 +1,7 @@
+## instance-variables
+
+## nil
+
 ## Object state, instance variables
 
 Objects can hold their own state by setting _instance variables_, which are created by prefixing `@` to a variable name.
diff --git a/exercises/concept/lasagna/.docs/introduction.md b/exercises/concept/lasagna/.docs/introduction.md
index 4808c0c153..b90f54e9d8 100644
--- a/exercises/concept/lasagna/.docs/introduction.md
+++ b/exercises/concept/lasagna/.docs/introduction.md
@@ -1,3 +1,5 @@
+## basics
+
 Ruby is a dynamic [object-oriented language][object-oriented-programming]. Everything in Ruby is an [object][object].
 
 There are two primary ways to assign objects to names in Ruby - using variables or constants. Variables are always written in [snake case][snake-case]. A variable can reference different objects over its lifetime. For example, `my_first_variable` can be defined and redefined many times using the `=` operator:
diff --git a/exercises/concept/numbers/.docs/introduction.md b/exercises/concept/numbers/.docs/introduction.md
index bf9d71ae7d..0de8e08e77 100644
--- a/exercises/concept/numbers/.docs/introduction.md
+++ b/exercises/concept/numbers/.docs/introduction.md
@@ -1,3 +1,7 @@
+## numbers
+
+## conditionals
+
 Two common types of numbers in Ruby are:
 
 - Integers: numbers with no digits behind the decimal separator (whole numbers). Examples are `-6`, `0`, `1`, `25`, `976` and `500000`.
diff --git a/exercises/concept/strings/.docs/introduction.md b/exercises/concept/strings/.docs/introduction.md
index b2515ab7bf..62530bdcd4 100644
--- a/exercises/concept/strings/.docs/introduction.md
+++ b/exercises/concept/strings/.docs/introduction.md
@@ -1 +1,3 @@
+## strings
+
 A `String` in Ruby is an object that holds and manipulates an arbitrary sequence of bytes, typically representing characters. Strings are manipulated by calling the string's methods.

From 31df7b098c62dd2c6a03f8b8b99a595b63d009e8 Mon Sep 17 00:00:00 2001
From: Erik Schierboom 
Date: Thu, 26 Nov 2020 10:34:11 +0100
Subject: [PATCH 068/102] instance-variables - replace about.md file with
 concept files

* Pre-populate instance-variables concept's about.md file from after.md file

* Pre-populate instance-variables concept's links.json file from after.md file

* Pre-populate nil concept's about.md file from after.md file

* Pre-populate nil concept's links.json file from after.md file

* instance-variables - Remove after.md document

* Update languages/concepts/instance-variables/about.md

Co-authored-by: Victor Goff 

* Update languages/concepts/nil/about.md

Co-authored-by: Victor Goff 

* Update languages/concepts/instance-variables/about.md

Co-authored-by: Victor Goff 

* Update languages/concepts/nil/about.md

Co-authored-by: Victor Goff 

* Update languages/concepts/nil/about.md

Co-authored-by: Victor Goff 

* Update languages/concepts/instance-variables/about.md

Co-authored-by: Victor Goff 

* Update languages/concepts/instance-variables/about.md

Co-authored-by: Victor Goff 

* [CI] Format code

Co-authored-by: Victor Goff 
Co-authored-by: github-actions[bot] 
---
 concepts/instance-variables/about.md          | 64 ++++++++++++++++++-
 concepts/instance-variables/links.json        | 27 +++++++-
 concepts/nil/about.md                         | 64 ++++++++++++++++++-
 concepts/nil/links.json                       | 27 +++++++-
 .../concept/instance-variables/.docs/after.md | 63 ------------------
 5 files changed, 178 insertions(+), 67 deletions(-)
 delete mode 100644 exercises/concept/instance-variables/.docs/after.md

diff --git a/concepts/instance-variables/about.md b/concepts/instance-variables/about.md
index ad578931b1..003910afc0 100644
--- a/concepts/instance-variables/about.md
+++ b/concepts/instance-variables/about.md
@@ -1 +1,63 @@
-TODO: add information on instance-variables concept
+## Key Points:
+
+- When a class' `.new` method is called to create an object instance, the `.initialize` method is passed all arguments to initialize the instance's state.
+- instance variable names are prefixed with `@`.
+- instance variables default to `nil` until they are explicitly set.
+- instance variables are private by default, and they should be manipulated with getters and setters
+
+```ruby
+class Backpack
+  initialize(owner)
+    @owner = owner
+  end
+
+  def owner
+    @owner
+  end
+
+  def owner=(new_owner)
+    @owner = new_owner
+  end
+end
+```
+
+- Methods named with a trailing `=` are recognized as setters by Ruby, and allow the syntactic "sugar" use of the assignment syntax, e.g. `Backpack.new("Sven").owner = "Ayah"`. Notice the space between `owner` and `=` while the actual method name is `owner=`.
+- Getters and setters can be created using the `attr_reader`, `attr_writer`, and `attr_accessor` methods:
+  - `attr_reader`: Create getters for the symbols listed
+  - `attr_writer`: Create setters for the symbols listed
+  - `attr_accessor`: Create getters and setters for the symbols listed
+
+```ruby
+class Backpack
+  attr_accessor :owner
+
+  initialize(owner)
+    @owner = owner
+  end
+end
+```
+
+- Why use getters and setters rather than the instance variable directly?
+  - If there was a typographical error (we call these "typo") in the previous example (e.g. `@ownar`), it would fail silently, potentially introducing a bug into the system.
+  - Getters and setters make this explicit, and will raise an error when a typo is made
+
+## References
+
+### Initializing object instances
+
+- [Ruby Guides: Initialize Method][rg-initialize-method]
+
+### Instance variables
+
+- [Ruby For Beginners: Instance variables][rfb-instance-variables]
+- [Ruby Guides: Instance variables][rg-instance-variables]
+- [Ruby User's Guide: Instance variables][rug-instance-variables]
+- [Geeks for Geeks: Ruby Getters and Setters Methods][gfg-getter-setters]
+- [Mix & Go: Ruby's attr_accessor, attr_reader, attr_writer][mg-attr]
+
+[mg-attr]: https://mixandgo.com/learn/ruby_attr_accessor_attr_reader_attr_writer
+[rfb-instance-variables]: http://ruby-for-beginners.rubymonstas.org/writing_classes/instance_variables.html
+[rg-initialize-method]: https://www.rubyguides.com/2019/01/ruby-initialize-method/
+[rg-instance-variables]: https://www.rubyguides.com/2019/07/ruby-instance-variables/
+[rug-instance-variables]: https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/instancevars.html
+[gfg-getter-setters]: https://www.geeksforgeeks.org/ruby-getters-and-setters-method/
diff --git a/concepts/instance-variables/links.json b/concepts/instance-variables/links.json
index fe51488c70..42d0ff212c 100644
--- a/concepts/instance-variables/links.json
+++ b/concepts/instance-variables/links.json
@@ -1 +1,26 @@
-[]
+[
+  {
+    "url": "https://www.rubyguides.com/2019/01/ruby-initialize-method/",
+    "description": "rg-initialize-method"
+  },
+  {
+    "url": "http://ruby-for-beginners.rubymonstas.org/writing_classes/instance_variables.html",
+    "description": "rfb-instance-variables"
+  },
+  {
+    "url": "https://www.rubyguides.com/2019/07/ruby-instance-variables/",
+    "description": "rg-instance-variables"
+  },
+  {
+    "url": "https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/instancevars.html",
+    "description": "rug-instance-variables"
+  },
+  {
+    "url": "https://www.geeksforgeeks.org/ruby-getters-and-setters-method/",
+    "description": "gfg-getter-setters"
+  },
+  {
+    "url": "https://mixandgo.com/learn/ruby_attr_accessor_attr_reader_attr_writer",
+    "description": "mg-attr"
+  }
+]
diff --git a/concepts/nil/about.md b/concepts/nil/about.md
index 19d56160bb..51f90cc44a 100644
--- a/concepts/nil/about.md
+++ b/concepts/nil/about.md
@@ -1 +1,63 @@
-TODO: add information on nil concept
+## Key Points:
+
+- When a class' `.new` method is called to create an object instance, the `.initialize` method is passed all arguments to initialize the instance's state.
+- instance variable names are prefixed with `@`.
+- instance variables default to `nil` until they are explicitly set.
+- instance variables are private by default, and they should be manipulated with getters and setters
+
+```ruby
+class Backpack
+  initialize(owner)
+    @owner = owner
+  end
+
+  def owner
+    @owner
+  end
+
+  def owner=(new_owner)
+    @owner = new_owner
+  end
+end
+```
+
+- Methods named with a trailing `=` are recognized as setters by Ruby, and allow the optional use of the assignment syntax, e.g. `Backpack.new("Sven").owner = "Ayah"`
+- Getters and setters can be shortened using the `attr_reader`, `attr_writer`, and `attr_accessor` methods:
+  - `attr_reader`: Create getters for the symbols listed
+  - `attr_writer`: Create setters for the symbols listed
+  - `attr_accessor`: Create getters and setters for the symbols listed
+
+```ruby
+class Backpack
+  attr_accessor :owner
+
+  initialize(owner)
+    @owner = owner
+  end
+end
+```
+
+- Why use getters and setters rather than the instance variable directly?
+  - If there was a typogrpahical error (we call this "typo") in the previous example (e.g. `@ownar`), it would silently be assigned `nil`, potentially introducing a bug into the system.
+  - Getters and setters make this explicit, and will raise an error when a typo is made
+
+## References
+
+### Initializing object instances
+
+- [Ruby Guides: Initialize Method][rg-initialize-method]
+
+### Instance variables
+
+- [Ruby For Beginners: Instance variables][rfb-instance-variables]
+- [Ruby Guides: Instance variables][rg-instance-variables]
+- [Ruby User's Guide: Instance variables][rug-instance-variables]
+- [Geeks for Geeks: Ruby Getters and Setters Methods][gfg-getter-setters]
+- [Mix & Go: Ruby's attr_accessor, attr_reader, attr_writer][mg-attr]
+
+[mg-attr]: https://mixandgo.com/learn/ruby_attr_accessor_attr_reader_attr_writer
+[rfb-instance-variables]: http://ruby-for-beginners.rubymonstas.org/writing_classes/instance_variables.html
+[rg-initialize-method]: https://www.rubyguides.com/2019/01/ruby-initialize-method/
+[rg-instance-variables]: https://www.rubyguides.com/2019/07/ruby-instance-variables/
+[rug-instance-variables]: https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/instancevars.html
+[gfg-getter-setters]: https://www.geeksforgeeks.org/ruby-getters-and-setters-method/
diff --git a/concepts/nil/links.json b/concepts/nil/links.json
index fe51488c70..42d0ff212c 100644
--- a/concepts/nil/links.json
+++ b/concepts/nil/links.json
@@ -1 +1,26 @@
-[]
+[
+  {
+    "url": "https://www.rubyguides.com/2019/01/ruby-initialize-method/",
+    "description": "rg-initialize-method"
+  },
+  {
+    "url": "http://ruby-for-beginners.rubymonstas.org/writing_classes/instance_variables.html",
+    "description": "rfb-instance-variables"
+  },
+  {
+    "url": "https://www.rubyguides.com/2019/07/ruby-instance-variables/",
+    "description": "rg-instance-variables"
+  },
+  {
+    "url": "https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/instancevars.html",
+    "description": "rug-instance-variables"
+  },
+  {
+    "url": "https://www.geeksforgeeks.org/ruby-getters-and-setters-method/",
+    "description": "gfg-getter-setters"
+  },
+  {
+    "url": "https://mixandgo.com/learn/ruby_attr_accessor_attr_reader_attr_writer",
+    "description": "mg-attr"
+  }
+]
diff --git a/exercises/concept/instance-variables/.docs/after.md b/exercises/concept/instance-variables/.docs/after.md
deleted file mode 100644
index 4bfd22f6d4..0000000000
--- a/exercises/concept/instance-variables/.docs/after.md
+++ /dev/null
@@ -1,63 +0,0 @@
-## Key Points:
-
-- When a class' `.new` method is called to create an object instance, the `.initialize` method is passed all arguments to initialize the instance's state.
-- instance variable names are prefixed with `@`.
-- instance variables default to `nil` until they are explicitly set.
-- instance variables are private by default, and they should be manipulated with getters and setters
-
-```ruby
-class Backpack
-  initialize(owner)
-    @owner = owner
-  end
-
-  def owner
-    @owner
-  end
-
-  def owner=(new_owner)
-    @owner = new_owner
-  end
-end
-```
-
-- Methods named with a trailing `=` are recognized as setters by ruby, and allow the optional use of the assignment syntax, e.g. `Backpack.new("Sven").owner = "Ayah"`
-- Getters and setters can be shortened using the `attr_reader`, `attr_writer`, and `attr_accessor` methods:
-  - `attr_reader`: Create getters for the symbols listed
-  - `attr_writer`: Create setters for the symbols listed
-  - `attr_accessor`: Create getters and setters for the symbols listed
-
-```ruby
-class Backpack
-  attr_accessor :owner
-
-  initialize(owner)
-    @owner = owner
-  end
-end
-```
-
-- Why use getters and setters rather than the instance variable directly?
-  - If there was a typo in the previous example (e.g. `@ownar`), it would fail silently, potentially introducing a bug into the system.
-  - Getters and setters make this explicit, and will raise an error when a typo is made
-
-## References
-
-### Initializing object instances
-
-- [Ruby Guides: Initialize Method][rg-initialize-method]
-
-### Instance variables
-
-- [Ruby For Beginners: Instance variables][rfb-instance-variables]
-- [Ruby Guides: Instance variables][rg-instance-variables]
-- [Ruby User's Guide: Instance variables][rug-instance-variables]
-- [Geeks for Geeks: Ruby Getters and Setters Methods][gfg-getter-setters]
-- [Mix & Go: Ruby's attr_accessor, attr_reader, attr_writer][mg-attr]
-
-[mg-attr]: https://mixandgo.com/learn/ruby_attr_accessor_attr_reader_attr_writer
-[rfb-instance-variables]: http://ruby-for-beginners.rubymonstas.org/writing_classes/instance_variables.html
-[rg-initialize-method]: https://www.rubyguides.com/2019/01/ruby-initialize-method/
-[rg-instance-variables]: https://www.rubyguides.com/2019/07/ruby-instance-variables/
-[rug-instance-variables]: https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/instancevars.html
-[gfg-getter-setters]: https://www.geeksforgeeks.org/ruby-getters-and-setters-method/

From 9108b7233c5a036a2807b8eb942bb44976670e8b Mon Sep 17 00:00:00 2001
From: Erik Schierboom 
Date: Fri, 8 Jan 2021 19:13:32 +0100
Subject: [PATCH 069/102] arrays - replace about.md file with concept files

* Pre-populate arrays concept's about.md file from after.md file

* Pre-populate arrays concept's links.json file from after.md file

* arrays - Remove after.md document
---
 concepts/arrays/about.md                | 55 ++++++++++++++++++++++++-
 concepts/arrays/links.json              |  7 +++-
 exercises/concept/arrays/.docs/after.md | 54 ------------------------
 3 files changed, 60 insertions(+), 56 deletions(-)
 delete mode 100644 exercises/concept/arrays/.docs/after.md

diff --git a/concepts/arrays/about.md b/concepts/arrays/about.md
index c54a50ebfc..3d78c7a5c5 100644
--- a/concepts/arrays/about.md
+++ b/concepts/arrays/about.md
@@ -1 +1,54 @@
-TODO: add information on arrays concept
+Data structures that can hold zero or more elements are known as _collections_. An **array** in Ruby is a collection that maintains the ordering in which its objects are added. Arrays can hold any object. Objects can be added to an array or retrieved from it using an index. Ruby array indexing is zero-based, meaning that the first element's index is always zero:
+
+```ruby
+# Declare an array containing two values
+two_ints = [1,2];
+
+# Assign first and second element by index
+two_ints[0] = 7;
+two_ints[1] = 8;
+
+# Retrieve the second element by index
+two_ints[1] # => 8
+
+# Check the length of the array
+two_ints.size # => 2
+```
+
+In Ruby there are multiple ways of creating an Array:
+
+- Using the literal constructor `[]` _(most common)_
+- Explicitly calling `Array.new`
+- Calling the Kernel `Array()` method
+
+The `Array.new` method supports two optional arguments: the initial size of the array and a default object.
+
+When a size and default are provided, the array is populated with `size` copies of default object.
+
+```ruby
+a = Array.new(2, Hash.new)
+# => [{}, {}]
+```
+
+Since all the Array elements store the same hash, changes to one of them will affect them all.
+
+```ruby
+a[0]['cat'] = 'feline'
+a # => [{"cat"=>"feline"}, {"cat"=>"feline"}]
+
+a[1]['cat'] = 'Felix'
+a # => [{"cat"=>"Felix"}, {"cat"=>"Felix"}]
+```
+
+If multiple copies are what you want, you should use the block version which uses the result of that block each time an element of the array needs to be initialized:
+
+```ruby
+a = Array.new(2) {Hash.new}
+a[0]['cat'] = 'feline'
+a # => [{"cat"=>"feline"}, {}]
+```
+
+Another characteristic of Ruby arrays is that they mix in the [Enumerable][enumerable-module] module, which adds a lot of handy methods to iterate, search, sort, filter, etc. elements of an array.
+
+[enumerable-module]: https://ruby-doc.org/core-2.7.1/Enumerable.html
+[for-loop]: https://launchschool.com/books/ruby/read/loops_iterators#forloops
diff --git a/concepts/arrays/links.json b/concepts/arrays/links.json
index fe51488c70..4dc034f96c 100644
--- a/concepts/arrays/links.json
+++ b/concepts/arrays/links.json
@@ -1 +1,6 @@
-[]
+[
+  {
+    "url": "https://ruby-doc.org/core-2.7.1/Enumerable.html",
+    "description": "enumerable-module"
+  }
+]
diff --git a/exercises/concept/arrays/.docs/after.md b/exercises/concept/arrays/.docs/after.md
deleted file mode 100644
index 3d78c7a5c5..0000000000
--- a/exercises/concept/arrays/.docs/after.md
+++ /dev/null
@@ -1,54 +0,0 @@
-Data structures that can hold zero or more elements are known as _collections_. An **array** in Ruby is a collection that maintains the ordering in which its objects are added. Arrays can hold any object. Objects can be added to an array or retrieved from it using an index. Ruby array indexing is zero-based, meaning that the first element's index is always zero:
-
-```ruby
-# Declare an array containing two values
-two_ints = [1,2];
-
-# Assign first and second element by index
-two_ints[0] = 7;
-two_ints[1] = 8;
-
-# Retrieve the second element by index
-two_ints[1] # => 8
-
-# Check the length of the array
-two_ints.size # => 2
-```
-
-In Ruby there are multiple ways of creating an Array:
-
-- Using the literal constructor `[]` _(most common)_
-- Explicitly calling `Array.new`
-- Calling the Kernel `Array()` method
-
-The `Array.new` method supports two optional arguments: the initial size of the array and a default object.
-
-When a size and default are provided, the array is populated with `size` copies of default object.
-
-```ruby
-a = Array.new(2, Hash.new)
-# => [{}, {}]
-```
-
-Since all the Array elements store the same hash, changes to one of them will affect them all.
-
-```ruby
-a[0]['cat'] = 'feline'
-a # => [{"cat"=>"feline"}, {"cat"=>"feline"}]
-
-a[1]['cat'] = 'Felix'
-a # => [{"cat"=>"Felix"}, {"cat"=>"Felix"}]
-```
-
-If multiple copies are what you want, you should use the block version which uses the result of that block each time an element of the array needs to be initialized:
-
-```ruby
-a = Array.new(2) {Hash.new}
-a[0]['cat'] = 'feline'
-a # => [{"cat"=>"feline"}, {}]
-```
-
-Another characteristic of Ruby arrays is that they mix in the [Enumerable][enumerable-module] module, which adds a lot of handy methods to iterate, search, sort, filter, etc. elements of an array.
-
-[enumerable-module]: https://ruby-doc.org/core-2.7.1/Enumerable.html
-[for-loop]: https://launchschool.com/books/ruby/read/loops_iterators#forloops

From f1bc7d64a4ca155c3f76fef5db8e6ba6259a9685 Mon Sep 17 00:00:00 2001
From: Erik Schierboom 
Date: Fri, 8 Jan 2021 19:19:58 +0100
Subject: [PATCH 070/102] strings - replace about.md file with concept files

* Pre-populate strings concept's about.md file from after.md file

* Pre-populate strings concept's links.json file from after.md file

* strings - Remove after.md document
---
 concepts/strings/about.md                | 10 +++++++++-
 concepts/strings/links.json              | 15 ++++++++++++++-
 exercises/concept/strings/.docs/after.md |  9 ---------
 3 files changed, 23 insertions(+), 11 deletions(-)
 delete mode 100644 exercises/concept/strings/.docs/after.md

diff --git a/concepts/strings/about.md b/concepts/strings/about.md
index b046260477..493d294a0e 100644
--- a/concepts/strings/about.md
+++ b/concepts/strings/about.md
@@ -1 +1,9 @@
-TODO: add information on strings concept
+The key thing to remember about Ruby strings is that they are objects that you call methods on. You can find all the methods in the [Ruby docs][ruby-doc.org-string]
+
+It's also worth knowing that strings can be created using single quotes (`'`) or double quotes (`"`). Single-quoted strings don't process ASCII escape codes(\n, \t etc.), and they don't do [string interpolation][ruby-for-beginners.rubymonstas.org-interpolation] while double-quoted does both.
+
+You can also create strings using the [heredoc syntax][ruby-heredoc] or using the `%q` and `%Q` helpers.
+
+[ruby-for-beginners.rubymonstas.org-interpolation]: http://ruby-for-beginners.rubymonstas.org/bonus/string_interpolation.html
+[ruby-doc.org-string]: https://ruby-doc.org/core-2.7.0/String.html
+[ruby-heredoc]: https://www.rubyguides.com/2018/11/ruby-heredoc/
diff --git a/concepts/strings/links.json b/concepts/strings/links.json
index fe51488c70..55b943ee3c 100644
--- a/concepts/strings/links.json
+++ b/concepts/strings/links.json
@@ -1 +1,14 @@
-[]
+[
+  {
+    "url": "https://ruby-doc.org/core-2.7.0/String.html",
+    "description": "ruby-doc.org-string"
+  },
+  {
+    "url": "http://ruby-for-beginners.rubymonstas.org/bonus/string_interpolation.html",
+    "description": "ruby-for-beginners.rubymonstas.org-interpolation"
+  },
+  {
+    "url": "https://www.rubyguides.com/2018/11/ruby-heredoc/",
+    "description": "ruby-heredoc"
+  }
+]
diff --git a/exercises/concept/strings/.docs/after.md b/exercises/concept/strings/.docs/after.md
deleted file mode 100644
index 493d294a0e..0000000000
--- a/exercises/concept/strings/.docs/after.md
+++ /dev/null
@@ -1,9 +0,0 @@
-The key thing to remember about Ruby strings is that they are objects that you call methods on. You can find all the methods in the [Ruby docs][ruby-doc.org-string]
-
-It's also worth knowing that strings can be created using single quotes (`'`) or double quotes (`"`). Single-quoted strings don't process ASCII escape codes(\n, \t etc.), and they don't do [string interpolation][ruby-for-beginners.rubymonstas.org-interpolation] while double-quoted does both.
-
-You can also create strings using the [heredoc syntax][ruby-heredoc] or using the `%q` and `%Q` helpers.
-
-[ruby-for-beginners.rubymonstas.org-interpolation]: http://ruby-for-beginners.rubymonstas.org/bonus/string_interpolation.html
-[ruby-doc.org-string]: https://ruby-doc.org/core-2.7.0/String.html
-[ruby-heredoc]: https://www.rubyguides.com/2018/11/ruby-heredoc/

From 33d8e5989cf23be13940725f91fa34f1641a5d4b Mon Sep 17 00:00:00 2001
From: Erik Schierboom 
Date: Fri, 8 Jan 2021 19:32:04 +0100
Subject: [PATCH 071/102] basics - replace about.md file with concept files

* Pre-populate basics concept's about.md file from after.md file

* Pre-populate basics concept's links.json file from after.md file

* basics - Remove after.md document
---
 concepts/basics/about.md   | 46 +++++++++++++++++++++++++++++++++++++-
 concepts/basics/links.json |  7 +++++-
 2 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/concepts/basics/about.md b/concepts/basics/about.md
index 246577017b..9b14ae5c43 100644
--- a/concepts/basics/about.md
+++ b/concepts/basics/about.md
@@ -1 +1,45 @@
-TODO: add information on basics concept
+Ruby is a dynamic and strongly typed language. In dynamic languages the type of a variable or object is resolved at runtime, which means that its value or type can be changed up to the very last moment (when it gets parsed by the interpreter).
+And what do we mean with strongly typed? Once we know the type of a variable or object, Ruby is strict about what you can do with it, for example:
+
+```ruby
+x = '2'
+y = x + 'n'
+=>  '2n'
+```
+
+**But**
+
+````ruby
+x = '2'
+y = x + 2
+=> TypeError (no implicit conversion of Integer into String)
+
+Remember, in Ruby everything is an object. Even classes are instances of the class `Class`. For example:
+
+```ruby
+1.class
+=> Integer
+
+Integer.is_a?(Object)
+# => true
+
+Class.is_a?(Object)
+# => true
+````
+
+This means that we can also define classes like this:
+
+```ruby
+Car = Class.new do
+  def run
+    'running'
+  end
+end
+
+Car.new.run
+=> 'running'
+```
+
+Finally, bear in mind that the `Integer` object holds values that may be defined as one or more (consecutive) digits and its methods support many of the [mathematical operators][integers-docs].
+
+[integers-docs]: https://ruby-doc.org/core-2.7.0/Integer.html
diff --git a/concepts/basics/links.json b/concepts/basics/links.json
index fe51488c70..3672d2c252 100644
--- a/concepts/basics/links.json
+++ b/concepts/basics/links.json
@@ -1 +1,6 @@
-[]
+[
+  {
+    "url": "https://ruby-doc.org/core-2.7.0/Integer.html",
+    "description": "integers-docs"
+  }
+]

From dded285cc0e9fe588a624b54e29c31f87830690d Mon Sep 17 00:00:00 2001
From: Erik Schierboom 
Date: Fri, 8 Jan 2021 19:32:36 +0100
Subject: [PATCH 072/102] booleans - replace about.md file with concept files

* Pre-populate booleans concept's about.md file from after.md file

* Pre-populate booleans concept's links.json file from after.md file

* booleans - Remove after.md document
---
 concepts/booleans/about.md                | 56 ++++++++++++++++++++++-
 concepts/booleans/links.json              | 27 ++++++++++-
 exercises/concept/booleans/.docs/after.md | 55 ----------------------
 3 files changed, 81 insertions(+), 57 deletions(-)
 delete mode 100644 exercises/concept/booleans/.docs/after.md

diff --git a/concepts/booleans/about.md b/concepts/booleans/about.md
index d461152b95..f890230093 100644
--- a/concepts/booleans/about.md
+++ b/concepts/booleans/about.md
@@ -1 +1,55 @@
-TODO: add information on booleans concept
+## True, False
+
+- `true` and `false` are used to represent boolean logical states.
+  - They are singleton instances of the [`TrueClass`][true-class] and [`FalseClass`][false-class] objects.
+  - they may occur as literals in code, or as the result of logical (`&&`, `||`, `!`) or [comparison][comparable-class] (`<`, `>`, `==`) methods.
+
+## _Truthy_ and _falsey_
+
+- When not using strict Boolean values, _truthy_ and _falsey_ evaluation rules are applied:
+
+  - Only `false` and `nil` evaluates as _falsey_.
+  - Everything else evaluates as _truthy_.
+
+  ```ruby
+  # A simplified definition
+  def falsey
+    nil || false
+  end
+
+  def truthy
+    not falsey
+  end
+  ```
+
+- It is common to use _truthy_ and _falsey_ values to determine the outcome of [conditional statements][control-expressions].
+
+  - `if`…`else` exists as a construct, similar to the [_C-family_ of programming languages][c-family]
+  - it is often more idiomatic to use `if` and `unless` as [expression modifiers to "guard" an expression][if-modifier]
+
+  ```ruby
+  1 + 1 if truthy
+  # => this will evaluate and return 2
+
+  2 + 2 if falsey
+  # => the numbers are not added because of the modifier, nil is returned
+
+  3 + 3 unless truthy
+  # => the numbers are not added because of the modifier, nil is returned
+
+  4 + 4 unless falsey
+  # => this will evaluate and return 8
+  ```
+
+[c-family]: https://en.wikipedia.org/wiki/List_of_C-family_programming_languages
+[control-expressions]: https://docs.ruby-lang.org/en/master/syntax/control_expressions_rdoc.html
+[if-modifier]: https://docs.ruby-lang.org/en/master/syntax/control_expressions_rdoc.html#label-Modifier+if+and+unless
+[true-class]: https://docs.ruby-lang.org/en/master/TrueClass.html
+[false-class]: https://docs.ruby-lang.org/en/master/FalseClass.html
+[nil-class]: https://docs.ruby-lang.org/en/master/NilClass.html
+[comparable-class]: https://docs.ruby-lang.org/en/master/Comparable.html
+[constants]: https://www.rubyguides.com/2017/07/ruby-constants/
+[integer-class]: https://docs.ruby-lang.org/en/master/Integer.html
+[kernel-class]: https://docs.ruby-lang.org/en/master/Kernel.html
+[methods]: https://launchschool.com/books/ruby/read/methods
+[returns]: https://www.freecodecamp.org/news/idiomatic-ruby-writing-beautiful-code-6845c830c664/
diff --git a/concepts/booleans/links.json b/concepts/booleans/links.json
index fe51488c70..8695de3794 100644
--- a/concepts/booleans/links.json
+++ b/concepts/booleans/links.json
@@ -1 +1,26 @@
-[]
+[
+  {
+    "url": "https://docs.ruby-lang.org/en/master/TrueClass.html",
+    "description": "true-class"
+  },
+  {
+    "url": "https://docs.ruby-lang.org/en/master/FalseClass.html",
+    "description": "false-class"
+  },
+  {
+    "url": "https://docs.ruby-lang.org/en/master/Comparable.html",
+    "description": "comparable-class"
+  },
+  {
+    "url": "https://docs.ruby-lang.org/en/master/syntax/control_expressions_rdoc.html",
+    "description": "control-expressions"
+  },
+  {
+    "url": "https://en.wikipedia.org/wiki/List_of_C-family_programming_languages",
+    "description": "c-family"
+  },
+  {
+    "url": "https://docs.ruby-lang.org/en/master/syntax/control_expressions_rdoc.html#label-Modifier\u002Bif\u002Band\u002Bunless",
+    "description": "if-modifier"
+  }
+]
diff --git a/exercises/concept/booleans/.docs/after.md b/exercises/concept/booleans/.docs/after.md
deleted file mode 100644
index f890230093..0000000000
--- a/exercises/concept/booleans/.docs/after.md
+++ /dev/null
@@ -1,55 +0,0 @@
-## True, False
-
-- `true` and `false` are used to represent boolean logical states.
-  - They are singleton instances of the [`TrueClass`][true-class] and [`FalseClass`][false-class] objects.
-  - they may occur as literals in code, or as the result of logical (`&&`, `||`, `!`) or [comparison][comparable-class] (`<`, `>`, `==`) methods.
-
-## _Truthy_ and _falsey_
-
-- When not using strict Boolean values, _truthy_ and _falsey_ evaluation rules are applied:
-
-  - Only `false` and `nil` evaluates as _falsey_.
-  - Everything else evaluates as _truthy_.
-
-  ```ruby
-  # A simplified definition
-  def falsey
-    nil || false
-  end
-
-  def truthy
-    not falsey
-  end
-  ```
-
-- It is common to use _truthy_ and _falsey_ values to determine the outcome of [conditional statements][control-expressions].
-
-  - `if`…`else` exists as a construct, similar to the [_C-family_ of programming languages][c-family]
-  - it is often more idiomatic to use `if` and `unless` as [expression modifiers to "guard" an expression][if-modifier]
-
-  ```ruby
-  1 + 1 if truthy
-  # => this will evaluate and return 2
-
-  2 + 2 if falsey
-  # => the numbers are not added because of the modifier, nil is returned
-
-  3 + 3 unless truthy
-  # => the numbers are not added because of the modifier, nil is returned
-
-  4 + 4 unless falsey
-  # => this will evaluate and return 8
-  ```
-
-[c-family]: https://en.wikipedia.org/wiki/List_of_C-family_programming_languages
-[control-expressions]: https://docs.ruby-lang.org/en/master/syntax/control_expressions_rdoc.html
-[if-modifier]: https://docs.ruby-lang.org/en/master/syntax/control_expressions_rdoc.html#label-Modifier+if+and+unless
-[true-class]: https://docs.ruby-lang.org/en/master/TrueClass.html
-[false-class]: https://docs.ruby-lang.org/en/master/FalseClass.html
-[nil-class]: https://docs.ruby-lang.org/en/master/NilClass.html
-[comparable-class]: https://docs.ruby-lang.org/en/master/Comparable.html
-[constants]: https://www.rubyguides.com/2017/07/ruby-constants/
-[integer-class]: https://docs.ruby-lang.org/en/master/Integer.html
-[kernel-class]: https://docs.ruby-lang.org/en/master/Kernel.html
-[methods]: https://launchschool.com/books/ruby/read/methods
-[returns]: https://www.freecodecamp.org/news/idiomatic-ruby-writing-beautiful-code-6845c830c664/

From bfd04d21a0cf0a733f1e5c9527e5b654ba8036dd Mon Sep 17 00:00:00 2001
From: Erik Schierboom 
Date: Fri, 8 Jan 2021 19:32:55 +0100
Subject: [PATCH 073/102] floating-point-numbers - replace about.md file with
 concept files

* Pre-populate floating-point-numbers concept's about.md file from after.md file

* Pre-populate floating-point-numbers concept's links.json file from after.md file

* Pre-populate loops concept's about.md file from after.md file

* Pre-populate loops concept's links.json file from after.md file

* floating-point-numbers - Remove after.md document
---
 concepts/floating-point-numbers/about.md      | 54 ++++++++++++++++++-
 concepts/floating-point-numbers/links.json    | 15 +++++-
 concepts/loops/about.md                       | 54 ++++++++++++++++++-
 concepts/loops/links.json                     | 15 +++++-
 .../floating-point-numbers/.docs/after.md     | 53 ------------------
 5 files changed, 134 insertions(+), 57 deletions(-)
 delete mode 100644 exercises/concept/floating-point-numbers/.docs/after.md

diff --git a/concepts/floating-point-numbers/about.md b/concepts/floating-point-numbers/about.md
index 4b9cdcc49c..a31d87ed0c 100644
--- a/concepts/floating-point-numbers/about.md
+++ b/concepts/floating-point-numbers/about.md
@@ -1 +1,53 @@
-TODO: add information on floating-point-numbers concept
+A floating-point number is a number with zero or more digits behind the decimal separator. Examples are `4.0`, `0.1`, `3.14`, `-6.4` `16.984025` and `1024.0`. In Ruby, floating-point numbers are implemented through the [Float](https://ruby-doc.org/core-2.7.0/Float.html) class.
+
+You can find a short introduction to floating-point numbers at [0.30000000000000004.com][0.30000000000000004.com].
+
+The [Float Toy page][evanw.github.io-float-toy] has a nice, graphical explanation how a floating-point numbers' bits are converted to an actual floating-point value.
+
+To repeatedly execute logic, one can use loops. In this example the `while` loop is useful because it keeps on looping _while_ a condition evaluates to some truthy value (i.e. not `false` or `nil`). Ruby implements a loop similar to the `while` loop. It's called the `until` loop, and you've probably guessed what it does. It keeps looping _until_ a boolean condition evaluates to `true`. In some languages, to make a piece of code execute an unlimited number of times, constructs like `while true` are used. In Ruby, the `loop` loop exists for that purpose. Even though the `loop` loop does not depend on a single condition, it can be canceled by using a `return` or `break` keyword.
+
+The `#years_before_desired_balance` method from the previous exercise could have been written by using any of the three mentioned loops:
+
+### `while`
+
+```ruby
+def self.years_before_desired_balance(current_balance, desired_balance)
+  years = 0
+  while current_balance < desired_balance
+    current_balance = annual_balance_update(current_balance)
+    years += 1
+  end
+  years
+end
+```
+
+### `until`
+
+```ruby
+def self.years_before_desired_balance(current_balance, desired_balance)
+  years = 0
+  until current_balance >= desired_balance
+    current_balance = annual_balance_update(current_balance)
+    years += 1
+  end
+  years
+end
+```
+
+### `loop`
+
+```ruby
+def self.years_before_desired_balance(current_balance, desired_balance)
+  years = 0
+  loop do
+    current_balance = annual_balance_update(current_balance)
+    years += 1
+    return years if current_balance >= desired_balance
+  end
+end
+```
+
+As you have probably noticed, Ruby has no increment operator (`i++`) like some other languages do. Instead, constructs like `i += 1` (which is equal to `i = i + 1`) can be used.
+
+[0.30000000000000004.com]: https://0.30000000000000004.com/
+[evanw.github.io-float-toy]: https://evanw.github.io/float-toy/
diff --git a/concepts/floating-point-numbers/links.json b/concepts/floating-point-numbers/links.json
index fe51488c70..20dc68f0a4 100644
--- a/concepts/floating-point-numbers/links.json
+++ b/concepts/floating-point-numbers/links.json
@@ -1 +1,14 @@
-[]
+[
+  {
+    "url": "https://ruby-doc.org/core-2.7.0/Float.html",
+    "description": "Float"
+  },
+  {
+    "url": "https://0.30000000000000004.com/",
+    "description": "0.30000000000000004.com"
+  },
+  {
+    "url": "https://evanw.github.io/float-toy/",
+    "description": "evanw.github.io-float-toy"
+  }
+]
diff --git a/concepts/loops/about.md b/concepts/loops/about.md
index b48612c67f..a31d87ed0c 100644
--- a/concepts/loops/about.md
+++ b/concepts/loops/about.md
@@ -1 +1,53 @@
-TODO: add information on loops concept
+A floating-point number is a number with zero or more digits behind the decimal separator. Examples are `4.0`, `0.1`, `3.14`, `-6.4` `16.984025` and `1024.0`. In Ruby, floating-point numbers are implemented through the [Float](https://ruby-doc.org/core-2.7.0/Float.html) class.
+
+You can find a short introduction to floating-point numbers at [0.30000000000000004.com][0.30000000000000004.com].
+
+The [Float Toy page][evanw.github.io-float-toy] has a nice, graphical explanation how a floating-point numbers' bits are converted to an actual floating-point value.
+
+To repeatedly execute logic, one can use loops. In this example the `while` loop is useful because it keeps on looping _while_ a condition evaluates to some truthy value (i.e. not `false` or `nil`). Ruby implements a loop similar to the `while` loop. It's called the `until` loop, and you've probably guessed what it does. It keeps looping _until_ a boolean condition evaluates to `true`. In some languages, to make a piece of code execute an unlimited number of times, constructs like `while true` are used. In Ruby, the `loop` loop exists for that purpose. Even though the `loop` loop does not depend on a single condition, it can be canceled by using a `return` or `break` keyword.
+
+The `#years_before_desired_balance` method from the previous exercise could have been written by using any of the three mentioned loops:
+
+### `while`
+
+```ruby
+def self.years_before_desired_balance(current_balance, desired_balance)
+  years = 0
+  while current_balance < desired_balance
+    current_balance = annual_balance_update(current_balance)
+    years += 1
+  end
+  years
+end
+```
+
+### `until`
+
+```ruby
+def self.years_before_desired_balance(current_balance, desired_balance)
+  years = 0
+  until current_balance >= desired_balance
+    current_balance = annual_balance_update(current_balance)
+    years += 1
+  end
+  years
+end
+```
+
+### `loop`
+
+```ruby
+def self.years_before_desired_balance(current_balance, desired_balance)
+  years = 0
+  loop do
+    current_balance = annual_balance_update(current_balance)
+    years += 1
+    return years if current_balance >= desired_balance
+  end
+end
+```
+
+As you have probably noticed, Ruby has no increment operator (`i++`) like some other languages do. Instead, constructs like `i += 1` (which is equal to `i = i + 1`) can be used.
+
+[0.30000000000000004.com]: https://0.30000000000000004.com/
+[evanw.github.io-float-toy]: https://evanw.github.io/float-toy/
diff --git a/concepts/loops/links.json b/concepts/loops/links.json
index fe51488c70..20dc68f0a4 100644
--- a/concepts/loops/links.json
+++ b/concepts/loops/links.json
@@ -1 +1,14 @@
-[]
+[
+  {
+    "url": "https://ruby-doc.org/core-2.7.0/Float.html",
+    "description": "Float"
+  },
+  {
+    "url": "https://0.30000000000000004.com/",
+    "description": "0.30000000000000004.com"
+  },
+  {
+    "url": "https://evanw.github.io/float-toy/",
+    "description": "evanw.github.io-float-toy"
+  }
+]
diff --git a/exercises/concept/floating-point-numbers/.docs/after.md b/exercises/concept/floating-point-numbers/.docs/after.md
deleted file mode 100644
index a31d87ed0c..0000000000
--- a/exercises/concept/floating-point-numbers/.docs/after.md
+++ /dev/null
@@ -1,53 +0,0 @@
-A floating-point number is a number with zero or more digits behind the decimal separator. Examples are `4.0`, `0.1`, `3.14`, `-6.4` `16.984025` and `1024.0`. In Ruby, floating-point numbers are implemented through the [Float](https://ruby-doc.org/core-2.7.0/Float.html) class.
-
-You can find a short introduction to floating-point numbers at [0.30000000000000004.com][0.30000000000000004.com].
-
-The [Float Toy page][evanw.github.io-float-toy] has a nice, graphical explanation how a floating-point numbers' bits are converted to an actual floating-point value.
-
-To repeatedly execute logic, one can use loops. In this example the `while` loop is useful because it keeps on looping _while_ a condition evaluates to some truthy value (i.e. not `false` or `nil`). Ruby implements a loop similar to the `while` loop. It's called the `until` loop, and you've probably guessed what it does. It keeps looping _until_ a boolean condition evaluates to `true`. In some languages, to make a piece of code execute an unlimited number of times, constructs like `while true` are used. In Ruby, the `loop` loop exists for that purpose. Even though the `loop` loop does not depend on a single condition, it can be canceled by using a `return` or `break` keyword.
-
-The `#years_before_desired_balance` method from the previous exercise could have been written by using any of the three mentioned loops:
-
-### `while`
-
-```ruby
-def self.years_before_desired_balance(current_balance, desired_balance)
-  years = 0
-  while current_balance < desired_balance
-    current_balance = annual_balance_update(current_balance)
-    years += 1
-  end
-  years
-end
-```
-
-### `until`
-
-```ruby
-def self.years_before_desired_balance(current_balance, desired_balance)
-  years = 0
-  until current_balance >= desired_balance
-    current_balance = annual_balance_update(current_balance)
-    years += 1
-  end
-  years
-end
-```
-
-### `loop`
-
-```ruby
-def self.years_before_desired_balance(current_balance, desired_balance)
-  years = 0
-  loop do
-    current_balance = annual_balance_update(current_balance)
-    years += 1
-    return years if current_balance >= desired_balance
-  end
-end
-```
-
-As you have probably noticed, Ruby has no increment operator (`i++`) like some other languages do. Instead, constructs like `i += 1` (which is equal to `i = i + 1`) can be used.
-
-[0.30000000000000004.com]: https://0.30000000000000004.com/
-[evanw.github.io-float-toy]: https://evanw.github.io/float-toy/

From 70f6cef6a2baee2b8f1d562ac4ec29edd5c6eefb Mon Sep 17 00:00:00 2001
From: Erik Schierboom 
Date: Fri, 8 Jan 2021 19:33:27 +0100
Subject: [PATCH 074/102] numbers - replace about.md file with concept files

* Pre-populate numbers concept's about.md file from after.md file

* Pre-populate numbers concept's links.json file from after.md file

* Pre-populate conditionals concept's about.md file from after.md file

* Pre-populate conditionals concept's links.json file from after.md file

* numbers - Remove after.md document
---
 concepts/conditionals/about.md           | 82 +++++++++++++++++++++++-
 concepts/conditionals/links.json         | 19 +++++-
 concepts/numbers/about.md                | 82 +++++++++++++++++++++++-
 concepts/numbers/links.json              | 19 +++++-
 exercises/concept/numbers/.docs/after.md | 81 -----------------------
 5 files changed, 198 insertions(+), 85 deletions(-)
 delete mode 100644 exercises/concept/numbers/.docs/after.md

diff --git a/concepts/conditionals/about.md b/concepts/conditionals/about.md
index 00d25f7851..92750518df 100644
--- a/concepts/conditionals/about.md
+++ b/concepts/conditionals/about.md
@@ -1 +1,81 @@
-TODO: add information on conditionals concept
+One of the key aspects of working with numbers in Ruby is the distinction between integers (numbers with no digits after the decimal separator) and floating-point numbers (numbers with zero or more digits after the decimal separator).
+They are implemented through the [`Integer`][integer-ruby] and [`Float`][float-ruby] class.
+
+```ruby
+a = 1
+b = 1.0
+a.class
+#=> Integer
+b.class
+#=> Float
+```
+
+- Arithmetic is done using the basic [arithmetic operators][arithmetic-operators] (`+`, `-`, `*`, `/`). Numbers can be compared using the standard [comparison operators][comparison-operators].
+- Basic arithmetic operations between instances of `Integer`, will always result in an instance of `Integer`.
+- Basic arithmetic operations between instances of `Float` will result in other instances of `Float`.
+- Basic arithmetic operations between instances of `Integer` and instances of `Float` will result in instances of `Float`.
+- The `Float` and `Integer` classes have methods that will coerce values from one to the other. `Integer` numbers are precise to a whole unit, while `Float` has precision that is fractional to an whole number. This means that coercing a float to an integer may result in loss of precision.
+
+```ruby
+4.9.to_i
+#=> 4
+
+5.to_f
+#=> 5.0
+
+7 - 3.0
+#=> 4.0
+
+2 == 4
+#=> false
+
+1.0 == 1
+#=> true
+```
+
+An `if` statement can be used to conditionally execute code:
+
+```ruby
+x = 5
+
+if x == 5
+  # Execute logic if x equals 5
+elsif x > 7
+  # Execute logic if x greater than 7
+else
+  # Execute logic in all other cases
+end
+```
+
+Sometimes you want to execute a statement (or statements) if a condition is _not_ true, for situations like that, Ruby implements the `unless` keyword:
+
+```ruby
+x = 4
+unless x == 5
+  # Execute logic if x does not equal 5
+else
+  # Execute logic if x == 5
+end
+```
+
+If you want to execute different code depending on the value of a variable, Ruby's `case` statement might come useful:
+
+```ruby
+y = 5
+case y
+when 3
+  # Execute logic if y equals 3
+when 5
+  # Execute logic if y equals 5
+else
+  # Execute logic in all other cases
+end
+```
+
+The same problem can sometimes be solved using different types of conditional statements, sometimes one might be more suited for the problem than the other. It's a good idea to stop for a moment and also consider the other two options when using any of the three conditional statements.
+
+[arithmetic-operators]: https://www.tutorialspoint.com/ruby/ruby_operators.htm
+[comparison-operators]: https://www.w3resource.com/ruby/ruby-comparison-operators.php
+[if-else-unless]: https://www.w3resource.com/ruby/ruby-if-else-unless.php
+[integer-ruby]: https://ruby-doc.org/core-2.7.1/Integer.html
+[float-ruby]: https://ruby-doc.org/core-2.7.1/Float.html
diff --git a/concepts/conditionals/links.json b/concepts/conditionals/links.json
index fe51488c70..a58c1c1b77 100644
--- a/concepts/conditionals/links.json
+++ b/concepts/conditionals/links.json
@@ -1 +1,18 @@
-[]
+[
+  {
+    "url": "https://ruby-doc.org/core-2.7.1/Integer.html",
+    "description": "integer-ruby"
+  },
+  {
+    "url": "https://ruby-doc.org/core-2.7.1/Float.html",
+    "description": "float-ruby"
+  },
+  {
+    "url": "https://www.tutorialspoint.com/ruby/ruby_operators.htm",
+    "description": "arithmetic-operators"
+  },
+  {
+    "url": "https://www.w3resource.com/ruby/ruby-comparison-operators.php",
+    "description": "comparison-operators"
+  }
+]
diff --git a/concepts/numbers/about.md b/concepts/numbers/about.md
index 36eb002377..92750518df 100644
--- a/concepts/numbers/about.md
+++ b/concepts/numbers/about.md
@@ -1 +1,81 @@
-TODO: add information on numbers concept
+One of the key aspects of working with numbers in Ruby is the distinction between integers (numbers with no digits after the decimal separator) and floating-point numbers (numbers with zero or more digits after the decimal separator).
+They are implemented through the [`Integer`][integer-ruby] and [`Float`][float-ruby] class.
+
+```ruby
+a = 1
+b = 1.0
+a.class
+#=> Integer
+b.class
+#=> Float
+```
+
+- Arithmetic is done using the basic [arithmetic operators][arithmetic-operators] (`+`, `-`, `*`, `/`). Numbers can be compared using the standard [comparison operators][comparison-operators].
+- Basic arithmetic operations between instances of `Integer`, will always result in an instance of `Integer`.
+- Basic arithmetic operations between instances of `Float` will result in other instances of `Float`.
+- Basic arithmetic operations between instances of `Integer` and instances of `Float` will result in instances of `Float`.
+- The `Float` and `Integer` classes have methods that will coerce values from one to the other. `Integer` numbers are precise to a whole unit, while `Float` has precision that is fractional to an whole number. This means that coercing a float to an integer may result in loss of precision.
+
+```ruby
+4.9.to_i
+#=> 4
+
+5.to_f
+#=> 5.0
+
+7 - 3.0
+#=> 4.0
+
+2 == 4
+#=> false
+
+1.0 == 1
+#=> true
+```
+
+An `if` statement can be used to conditionally execute code:
+
+```ruby
+x = 5
+
+if x == 5
+  # Execute logic if x equals 5
+elsif x > 7
+  # Execute logic if x greater than 7
+else
+  # Execute logic in all other cases
+end
+```
+
+Sometimes you want to execute a statement (or statements) if a condition is _not_ true, for situations like that, Ruby implements the `unless` keyword:
+
+```ruby
+x = 4
+unless x == 5
+  # Execute logic if x does not equal 5
+else
+  # Execute logic if x == 5
+end
+```
+
+If you want to execute different code depending on the value of a variable, Ruby's `case` statement might come useful:
+
+```ruby
+y = 5
+case y
+when 3
+  # Execute logic if y equals 3
+when 5
+  # Execute logic if y equals 5
+else
+  # Execute logic in all other cases
+end
+```
+
+The same problem can sometimes be solved using different types of conditional statements, sometimes one might be more suited for the problem than the other. It's a good idea to stop for a moment and also consider the other two options when using any of the three conditional statements.
+
+[arithmetic-operators]: https://www.tutorialspoint.com/ruby/ruby_operators.htm
+[comparison-operators]: https://www.w3resource.com/ruby/ruby-comparison-operators.php
+[if-else-unless]: https://www.w3resource.com/ruby/ruby-if-else-unless.php
+[integer-ruby]: https://ruby-doc.org/core-2.7.1/Integer.html
+[float-ruby]: https://ruby-doc.org/core-2.7.1/Float.html
diff --git a/concepts/numbers/links.json b/concepts/numbers/links.json
index fe51488c70..a58c1c1b77 100644
--- a/concepts/numbers/links.json
+++ b/concepts/numbers/links.json
@@ -1 +1,18 @@
-[]
+[
+  {
+    "url": "https://ruby-doc.org/core-2.7.1/Integer.html",
+    "description": "integer-ruby"
+  },
+  {
+    "url": "https://ruby-doc.org/core-2.7.1/Float.html",
+    "description": "float-ruby"
+  },
+  {
+    "url": "https://www.tutorialspoint.com/ruby/ruby_operators.htm",
+    "description": "arithmetic-operators"
+  },
+  {
+    "url": "https://www.w3resource.com/ruby/ruby-comparison-operators.php",
+    "description": "comparison-operators"
+  }
+]
diff --git a/exercises/concept/numbers/.docs/after.md b/exercises/concept/numbers/.docs/after.md
deleted file mode 100644
index 92750518df..0000000000
--- a/exercises/concept/numbers/.docs/after.md
+++ /dev/null
@@ -1,81 +0,0 @@
-One of the key aspects of working with numbers in Ruby is the distinction between integers (numbers with no digits after the decimal separator) and floating-point numbers (numbers with zero or more digits after the decimal separator).
-They are implemented through the [`Integer`][integer-ruby] and [`Float`][float-ruby] class.
-
-```ruby
-a = 1
-b = 1.0
-a.class
-#=> Integer
-b.class
-#=> Float
-```
-
-- Arithmetic is done using the basic [arithmetic operators][arithmetic-operators] (`+`, `-`, `*`, `/`). Numbers can be compared using the standard [comparison operators][comparison-operators].
-- Basic arithmetic operations between instances of `Integer`, will always result in an instance of `Integer`.
-- Basic arithmetic operations between instances of `Float` will result in other instances of `Float`.
-- Basic arithmetic operations between instances of `Integer` and instances of `Float` will result in instances of `Float`.
-- The `Float` and `Integer` classes have methods that will coerce values from one to the other. `Integer` numbers are precise to a whole unit, while `Float` has precision that is fractional to an whole number. This means that coercing a float to an integer may result in loss of precision.
-
-```ruby
-4.9.to_i
-#=> 4
-
-5.to_f
-#=> 5.0
-
-7 - 3.0
-#=> 4.0
-
-2 == 4
-#=> false
-
-1.0 == 1
-#=> true
-```
-
-An `if` statement can be used to conditionally execute code:
-
-```ruby
-x = 5
-
-if x == 5
-  # Execute logic if x equals 5
-elsif x > 7
-  # Execute logic if x greater than 7
-else
-  # Execute logic in all other cases
-end
-```
-
-Sometimes you want to execute a statement (or statements) if a condition is _not_ true, for situations like that, Ruby implements the `unless` keyword:
-
-```ruby
-x = 4
-unless x == 5
-  # Execute logic if x does not equal 5
-else
-  # Execute logic if x == 5
-end
-```
-
-If you want to execute different code depending on the value of a variable, Ruby's `case` statement might come useful:
-
-```ruby
-y = 5
-case y
-when 3
-  # Execute logic if y equals 3
-when 5
-  # Execute logic if y equals 5
-else
-  # Execute logic in all other cases
-end
-```
-
-The same problem can sometimes be solved using different types of conditional statements, sometimes one might be more suited for the problem than the other. It's a good idea to stop for a moment and also consider the other two options when using any of the three conditional statements.
-
-[arithmetic-operators]: https://www.tutorialspoint.com/ruby/ruby_operators.htm
-[comparison-operators]: https://www.w3resource.com/ruby/ruby-comparison-operators.php
-[if-else-unless]: https://www.w3resource.com/ruby/ruby-if-else-unless.php
-[integer-ruby]: https://ruby-doc.org/core-2.7.1/Integer.html
-[float-ruby]: https://ruby-doc.org/core-2.7.1/Float.html

From ac9913e9a1d8b1342ca9d7c8bd69a68c74a8b8c5 Mon Sep 17 00:00:00 2001
From: Erik Schierboom 
Date: Fri, 8 Jan 2021 15:10:44 +0100
Subject: [PATCH 075/102] Add concept introductions

---
 concepts/arrays/introduction.md               | 84 +++++++++++++++++++
 concepts/basics/introduction.md               | 55 ++++++++++++
 concepts/blocks/introduction.md               |  1 +
 concepts/booleans/introduction.md             | 64 ++++++++++++++
 concepts/classes/introduction.md              |  1 +
 concepts/conditionals/introduction.md         | 22 +++++
 .../floating-point-numbers/introduction.md    | 18 ++++
 concepts/instance-variables/introduction.md   | 62 ++++++++++++++
 concepts/loops/introduction.md                | 12 +++
 concepts/nil/introduction.md                  | 62 ++++++++++++++
 concepts/numbers/introduction.md              | 28 +++++++
 concepts/strings/introduction.md              |  1 +
 12 files changed, 410 insertions(+)
 create mode 100644 concepts/arrays/introduction.md
 create mode 100644 concepts/basics/introduction.md
 create mode 100644 concepts/blocks/introduction.md
 create mode 100644 concepts/booleans/introduction.md
 create mode 100644 concepts/classes/introduction.md
 create mode 100644 concepts/conditionals/introduction.md
 create mode 100644 concepts/floating-point-numbers/introduction.md
 create mode 100644 concepts/instance-variables/introduction.md
 create mode 100644 concepts/loops/introduction.md
 create mode 100644 concepts/nil/introduction.md
 create mode 100644 concepts/numbers/introduction.md
 create mode 100644 concepts/strings/introduction.md

diff --git a/concepts/arrays/introduction.md b/concepts/arrays/introduction.md
new file mode 100644
index 0000000000..8cbb007f6b
--- /dev/null
+++ b/concepts/arrays/introduction.md
@@ -0,0 +1,84 @@
+In Ruby, **arrays** are ordered, integer-indexed collections of any object. Array indexing starts at `0`. A negative index is assumed to be relative to the end of the array — i.e. an index of `-1` indicates the last element of the array, `-2` is the next to last element in the array, and so on.
+Ruby arrays mix in the [Enumerable module][enumerable-module], which adds several traversal and searching methods, and with the ability to sort.
+
+### Create array.
+
+- An array in Ruby can contain different types of objects.
+
+```ruby
+array = [1, "two", 3.0] #=> [1, "two", 3.0]
+```
+
+### Element Assignment
+
+Elements can accessed or changed using indexes. Subarrays can be accessed by specifying a start index and a size.
+
+```ruby
+a = ["", "", "", "", ""]
+
+a[4] = "hello"  #=> [nil, nil, nil, nil, "hello"]
+a[0, 3] = [ 'a', 'b', 'c' ] #=> ["a", "b", "c", nil, "hello"]
+```
+
+- Negative indices will count backward from the end of the array.
+
+```ruby
+a = ['a', 'b']
+
+a[-1] = "Z"
+a #=> ["a", "Z"]
+```
+
+### Element Reference
+
+- Elements in an array can be retrieved using the #[] method. It returns the element at index, or returns a subarray starting at the start index and continuing for length elements.
+
+```ruby
+a = [ "a", "b", "c", "d", "e" ]
+
+a[2]    #=> "c"
+a[6]    #=> nil
+a[1, 2] #=> [ "b", "c" ]
+```
+
+- Negative indices count backward from the end of the array (-1 is the last element)
+
+```ruby
+a = [ "a", "b", "c", "d", "e" ]
+
+a[-2]    #=> "d"
+a[-3, 3] #=> [ "c", "d", "e" ]
+```
+
+### Obtaining Information about an Array
+
+Arrays keep track of their own length at all times. To query an array about the number of elements it contains, use length, count or size.
+
+```ruby
+browsers = ['Chrome', 'Firefox', 'Safari', 'Opera', 'IE']
+browsers.length #=> 5
+browsers.count  #=> 5
+browsers.size   #=> 5
+```
+
+### Adding Items to Arrays
+
+Items can be added to the end of an array by using either push or <<
+
+```ruby
+arr = [1, 2, 3, 4]
+arr.push(5) #=> [1, 2, 3, 4, 5]
+arr << 6    #=> [1, 2, 3, 4, 5, 6]
+```
+
+### Removing Items from an Array
+
+The method pop removes the last element in an array and returns it
+
+```ruby
+arr =  [1, 2, 3, 4, 5, 6]
+arr.pop #=> 6
+arr     #=> [1, 2, 3, 4, 5]
+```
+
+[enumerable-module]: https://ruby-doc.org/core-2.7.1/Enumerable.html
\ No newline at end of file
diff --git a/concepts/basics/introduction.md b/concepts/basics/introduction.md
new file mode 100644
index 0000000000..6f83a38be2
--- /dev/null
+++ b/concepts/basics/introduction.md
@@ -0,0 +1,55 @@
+Ruby is a dynamic [object-oriented language][object-oriented-programming]. Everything in Ruby is an [object][object].
+
+There are two primary ways to assign objects to names in Ruby - using variables or constants. Variables are always written in [snake case][snake-case]. A variable can reference different objects over its lifetime. For example, `my_first_variable` can be defined and redefined many times using the `=` operator:
+
+```ruby
+my_first_variable = 1
+my_first_variable = "Some string"
+my_first_variable = SomeComplexObject.new
+```
+
+Constants, however, are meant to be assigned once. They must start with capital letters and are normally written in block capitals with words separated by underscores. For example:
+
+```ruby
+MY_FIRST_CONSTANT = 10
+
+# Redefining not allowed
+# MY_FIRST_CONSTANT = "Some String"
+```
+
+Ruby is organised into classes. Classes are defined using the `class` keyword followed by the name of the class. Objects are generally created by instantiating classes using the `.new` method. For example:
+
+```ruby
+# Define the class
+class Calculator
+  #...
+end
+
+# Create an instance of it and assign it to a variable
+my_first_calc = Calculator.new
+```
+
+Units of functionality are encapsulated in methods - similar to _functions_ in other languages. A method can optionally be defined with positional arguments, and/or keyword arguments that are defined and called using the `:` syntax. Methods either implicitly return the result of the last evaluated statement, or can explicitly return an object via the `return` keyword. Methods are invoked using `.` syntax.
+
+```ruby
+class Calculator
+
+  # Unnamed params
+  def add(num1, num2)
+    return num1 + num2 # Explicit return
+  end
+
+  # Named params
+  def multiply(num1:, num2:)
+    num1 * num2 # Implicit return
+  end
+end
+
+calc = Calculator.new
+calc.add(1, 3)
+calc.multiply(num1: 2, num_2: 5)
+```
+
+[object-oriented-programming]: https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/oothinking.html
+[object]: ../../../../../../reference/concepts/objects.md
+[snake-case]: https://en.wikipedia.org/wiki/Snake_case
\ No newline at end of file
diff --git a/concepts/blocks/introduction.md b/concepts/blocks/introduction.md
new file mode 100644
index 0000000000..2420d7ed24
--- /dev/null
+++ b/concepts/blocks/introduction.md
@@ -0,0 +1 @@
+TODO: add introduction for blocks concept
\ No newline at end of file
diff --git a/concepts/booleans/introduction.md b/concepts/booleans/introduction.md
new file mode 100644
index 0000000000..1107f71068
--- /dev/null
+++ b/concepts/booleans/introduction.md
@@ -0,0 +1,64 @@
+TODO: the content below is copied from the exercise introduction and probably needs rewriting to a proper concept introduction
+
+## booleans
+
+## True and False
+
+True and false logical states are represented with `true` and `false` in Ruby. These may either be used as literals on their own, or as a result of logical or comparison methods.
+
+```ruby
+happy = true
+sad = false
+
+true && false
+# => false
+
+1 < 2
+# => true
+```
+
+## _Truthy_ and _falsey_
+
+When evaluating objects in `if` statements or other boolean contexts, all objects evaluate as _truthy_ **except** for `false` and `nil`.
+
+## Control flow
+
+_Truthy_ and _falsey_ evaluations are useful in the context of control flow. Like in procedural languages, Ruby has an `if`...`else` construct, but it may be more common to use `if` as a "guarding" statement to modify the evaluation of an expression.
+
+```ruby
+def falsey
+  nil || false
+end
+
+def truthy
+  not falsey
+end
+
+if truthy
+  # this block is evaluated
+end
+
+if falsey
+  # this block is not evaluated
+else
+  # this block is evaluated
+end
+
+1 + 1 if truthy
+# => this will evaluate and return 2
+
+2 + 2 if falsey
+# => the numbers are not added because of the modifier, nil is returned
+```
+
+Ruby provides `unless` to make code read well. E.g.) Rather than `eat_desert if not too_full`, we can also write `eat_desert unless too_full`.
+
+```ruby
+3 + 3 unless truthy
+# => the numbers are not added because of the modifier, nil is returned
+
+4 + 4 unless falsey
+# => this will evaluate and return 8
+```
+
+[nil-dictionary]: https://www.merriam-webster.com/dictionary/nil
diff --git a/concepts/classes/introduction.md b/concepts/classes/introduction.md
new file mode 100644
index 0000000000..805903bdf5
--- /dev/null
+++ b/concepts/classes/introduction.md
@@ -0,0 +1 @@
+TODO: add introduction for classes concept
\ No newline at end of file
diff --git a/concepts/conditionals/introduction.md b/concepts/conditionals/introduction.md
new file mode 100644
index 0000000000..345ba56543
--- /dev/null
+++ b/concepts/conditionals/introduction.md
@@ -0,0 +1,22 @@
+Two common types of numbers in Ruby are:
+
+- Integers: numbers with no digits behind the decimal separator (whole numbers). Examples are `-6`, `0`, `1`, `25`, `976` and `500000`.
+- Floating-point numbers: numbers with zero or more digits behind the decimal separator. Examples are `-2.4`, `0.1`, `3.14`, `16.984025` and `1024.0`.
+
+They are implemented through the `Integer` and `Float` classes.
+
+The `Float` and `Integer` classes have methods that will coerce values from one to the other. `Integer` numbers are precise to a whole unit, while `Float` has precision that is fractional to an whole number.
+
+In this exercise you must conditionally execute logic. A common way to do this in Ruby is by using an `if/else` statement:
+
+```ruby
+x = 5
+
+if x == 5
+  # Execute logic if x equals 5
+elsif x > 7
+  # Execute logic if x greater than 7
+else
+  # Execute logic in all other cases
+end
+```
\ No newline at end of file
diff --git a/concepts/floating-point-numbers/introduction.md b/concepts/floating-point-numbers/introduction.md
new file mode 100644
index 0000000000..aff33f5e92
--- /dev/null
+++ b/concepts/floating-point-numbers/introduction.md
@@ -0,0 +1,18 @@
+TODO: the content below is copied from the exercise introduction and probably needs rewriting to a proper concept introduction
+
+## floating-point-numbers
+
+## loops
+
+A floating-point number is a number with zero or more digits behind the decimal separator. Examples are `4.0`, `0.1`, `3.14`, `-6.4` `16.984025` and `1024.0`.
+In Ruby, floating-point numbers are implemented through the [Float](https://ruby-doc.org/core-2.7.0/Float.html) class.
+
+In this exercise you may also want to use a loop. There are several ways to write loops in Ruby, one of them is the `while` loop:
+
+```ruby
+counter = 0
+
+while counter < 5
+  counter += 1
+end
+```
diff --git a/concepts/instance-variables/introduction.md b/concepts/instance-variables/introduction.md
new file mode 100644
index 0000000000..cfbb665e99
--- /dev/null
+++ b/concepts/instance-variables/introduction.md
@@ -0,0 +1,62 @@
+TODO: the content below is copied from the exercise introduction and probably needs rewriting to a proper concept introduction
+
+## instance-variables
+
+## nil
+
+## Object state, instance variables
+
+Objects can hold their own state by setting _instance variables_, which are created by prefixing `@` to a variable name.
+
+```ruby
+@name = 2
+```
+
+Objects usually set their initial state in an `initialize` method, which is automatically called when calling `new` on a class.
+
+```ruby
+class Airplane
+  def initialize
+    @wings = 2
+  end
+end
+```
+
+The `initialize` method may also take arguments, so that each instance can start with a custom state:
+
+```ruby
+class Suitcase
+  def initialize(locked)
+    @locked = locked
+  end
+end
+```
+
+Consider _instance_ variables to be private from external read and writes. _Instance_ methods should be used for getting and setting instance variables:
+
+```ruby
+class Suitcase
+  #...
+
+  def locked? # Query methods should be named with a trailing `?`
+    @locked
+  end
+
+  def unlock! # Methods which mutate state should have trailing `!`
+    @locked = false
+  end
+end
+```
+
+## Nil
+
+[Nil][nil-dictionary] is an English word meaning "nothing" or "zero". In Ruby, `nil` is used to express the _absence_ of an object. In other programming languages, `null` or `none` values may play a similar role.
+
+```ruby
+# I do not have a favorite color
+favorite_color = nil
+```
+
+Ruby gives any instance variable the default value of `nil` when it is first encountered, until it is set otherwise.
+
+[nil-dictionary]: https://www.merriam-webster.com/dictionary/nil
diff --git a/concepts/loops/introduction.md b/concepts/loops/introduction.md
new file mode 100644
index 0000000000..b6d9af9088
--- /dev/null
+++ b/concepts/loops/introduction.md
@@ -0,0 +1,12 @@
+A floating-point number is a number with zero or more digits behind the decimal separator. Examples are `4.0`, `0.1`, `3.14`, `-6.4` `16.984025` and `1024.0`.
+In Ruby, floating-point numbers are implemented through the [Float](https://ruby-doc.org/core-2.7.0/Float.html) class.
+
+In this exercise you may also want to use a loop. There are several ways to write loops in Ruby, one of them is the `while` loop:
+
+```ruby
+counter = 0
+
+while counter < 5
+  counter += 1
+end
+```
\ No newline at end of file
diff --git a/concepts/nil/introduction.md b/concepts/nil/introduction.md
new file mode 100644
index 0000000000..cfbb665e99
--- /dev/null
+++ b/concepts/nil/introduction.md
@@ -0,0 +1,62 @@
+TODO: the content below is copied from the exercise introduction and probably needs rewriting to a proper concept introduction
+
+## instance-variables
+
+## nil
+
+## Object state, instance variables
+
+Objects can hold their own state by setting _instance variables_, which are created by prefixing `@` to a variable name.
+
+```ruby
+@name = 2
+```
+
+Objects usually set their initial state in an `initialize` method, which is automatically called when calling `new` on a class.
+
+```ruby
+class Airplane
+  def initialize
+    @wings = 2
+  end
+end
+```
+
+The `initialize` method may also take arguments, so that each instance can start with a custom state:
+
+```ruby
+class Suitcase
+  def initialize(locked)
+    @locked = locked
+  end
+end
+```
+
+Consider _instance_ variables to be private from external read and writes. _Instance_ methods should be used for getting and setting instance variables:
+
+```ruby
+class Suitcase
+  #...
+
+  def locked? # Query methods should be named with a trailing `?`
+    @locked
+  end
+
+  def unlock! # Methods which mutate state should have trailing `!`
+    @locked = false
+  end
+end
+```
+
+## Nil
+
+[Nil][nil-dictionary] is an English word meaning "nothing" or "zero". In Ruby, `nil` is used to express the _absence_ of an object. In other programming languages, `null` or `none` values may play a similar role.
+
+```ruby
+# I do not have a favorite color
+favorite_color = nil
+```
+
+Ruby gives any instance variable the default value of `nil` when it is first encountered, until it is set otherwise.
+
+[nil-dictionary]: https://www.merriam-webster.com/dictionary/nil
diff --git a/concepts/numbers/introduction.md b/concepts/numbers/introduction.md
new file mode 100644
index 0000000000..9e1c8ab66f
--- /dev/null
+++ b/concepts/numbers/introduction.md
@@ -0,0 +1,28 @@
+TODO: the content below is copied from the exercise introduction and probably needs rewriting to a proper concept introduction
+
+## numbers
+
+## conditionals
+
+Two common types of numbers in Ruby are:
+
+- Integers: numbers with no digits behind the decimal separator (whole numbers). Examples are `-6`, `0`, `1`, `25`, `976` and `500000`.
+- Floating-point numbers: numbers with zero or more digits behind the decimal separator. Examples are `-2.4`, `0.1`, `3.14`, `16.984025` and `1024.0`.
+
+They are implemented through the `Integer` and `Float` classes.
+
+The `Float` and `Integer` classes have methods that will coerce values from one to the other. `Integer` numbers are precise to a whole unit, while `Float` has precision that is fractional to an whole number.
+
+In this exercise you must conditionally execute logic. A common way to do this in Ruby is by using an `if/else` statement:
+
+```ruby
+x = 5
+
+if x == 5
+  # Execute logic if x equals 5
+elsif x > 7
+  # Execute logic if x greater than 7
+else
+  # Execute logic in all other cases
+end
+```
diff --git a/concepts/strings/introduction.md b/concepts/strings/introduction.md
new file mode 100644
index 0000000000..649ba40eb4
--- /dev/null
+++ b/concepts/strings/introduction.md
@@ -0,0 +1 @@
+A `String` in Ruby is an object that holds and manipulates an arbitrary sequence of bytes, typically representing characters. Strings are manipulated by calling the string's methods.
\ No newline at end of file

From 5bbfd3b936c968d782e1bbc9aa7691eb4896d4fc Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" 
Date: Fri, 8 Jan 2021 14:16:27 +0000
Subject: [PATCH 076/102] Format code

---
 concepts/arrays/introduction.md       | 2 +-
 concepts/basics/introduction.md       | 2 +-
 concepts/blocks/introduction.md       | 2 +-
 concepts/classes/introduction.md      | 2 +-
 concepts/conditionals/introduction.md | 2 +-
 concepts/loops/introduction.md        | 2 +-
 concepts/strings/introduction.md      | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/concepts/arrays/introduction.md b/concepts/arrays/introduction.md
index 8cbb007f6b..ac17cb6f6b 100644
--- a/concepts/arrays/introduction.md
+++ b/concepts/arrays/introduction.md
@@ -81,4 +81,4 @@ arr.pop #=> 6
 arr     #=> [1, 2, 3, 4, 5]
 ```
 
-[enumerable-module]: https://ruby-doc.org/core-2.7.1/Enumerable.html
\ No newline at end of file
+[enumerable-module]: https://ruby-doc.org/core-2.7.1/Enumerable.html
diff --git a/concepts/basics/introduction.md b/concepts/basics/introduction.md
index 6f83a38be2..4808c0c153 100644
--- a/concepts/basics/introduction.md
+++ b/concepts/basics/introduction.md
@@ -52,4 +52,4 @@ calc.multiply(num1: 2, num_2: 5)
 
 [object-oriented-programming]: https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/oothinking.html
 [object]: ../../../../../../reference/concepts/objects.md
-[snake-case]: https://en.wikipedia.org/wiki/Snake_case
\ No newline at end of file
+[snake-case]: https://en.wikipedia.org/wiki/Snake_case
diff --git a/concepts/blocks/introduction.md b/concepts/blocks/introduction.md
index 2420d7ed24..c7bbbd2213 100644
--- a/concepts/blocks/introduction.md
+++ b/concepts/blocks/introduction.md
@@ -1 +1 @@
-TODO: add introduction for blocks concept
\ No newline at end of file
+TODO: add introduction for blocks concept
diff --git a/concepts/classes/introduction.md b/concepts/classes/introduction.md
index 805903bdf5..cacf371834 100644
--- a/concepts/classes/introduction.md
+++ b/concepts/classes/introduction.md
@@ -1 +1 @@
-TODO: add introduction for classes concept
\ No newline at end of file
+TODO: add introduction for classes concept
diff --git a/concepts/conditionals/introduction.md b/concepts/conditionals/introduction.md
index 345ba56543..bf9d71ae7d 100644
--- a/concepts/conditionals/introduction.md
+++ b/concepts/conditionals/introduction.md
@@ -19,4 +19,4 @@ elsif x > 7
 else
   # Execute logic in all other cases
 end
-```
\ No newline at end of file
+```
diff --git a/concepts/loops/introduction.md b/concepts/loops/introduction.md
index b6d9af9088..050095f094 100644
--- a/concepts/loops/introduction.md
+++ b/concepts/loops/introduction.md
@@ -9,4 +9,4 @@ counter = 0
 while counter < 5
   counter += 1
 end
-```
\ No newline at end of file
+```
diff --git a/concepts/strings/introduction.md b/concepts/strings/introduction.md
index 649ba40eb4..b2515ab7bf 100644
--- a/concepts/strings/introduction.md
+++ b/concepts/strings/introduction.md
@@ -1 +1 @@
-A `String` in Ruby is an object that holds and manipulates an arbitrary sequence of bytes, typically representing characters. Strings are manipulated by calling the string's methods.
\ No newline at end of file
+A `String` in Ruby is an object that holds and manipulates an arbitrary sequence of bytes, typically representing characters. Strings are manipulated by calling the string's methods.

From 4c8e03709a6c2e4edf73d97020a0f4003658e0a8 Mon Sep 17 00:00:00 2001
From: Erik Schierboom 
Date: Fri, 8 Jan 2021 15:17:21 +0100
Subject: [PATCH 077/102] Update introduction.md

---
 concepts/basics/introduction.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/concepts/basics/introduction.md b/concepts/basics/introduction.md
index 4808c0c153..754cdc9a2e 100644
--- a/concepts/basics/introduction.md
+++ b/concepts/basics/introduction.md
@@ -51,5 +51,5 @@ calc.multiply(num1: 2, num_2: 5)
 ```
 
 [object-oriented-programming]: https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/oothinking.html
-[object]: ../../../../../../reference/concepts/objects.md
+[object]: ../../../../reference/concepts/objects.md
 [snake-case]: https://en.wikipedia.org/wiki/Snake_case

From 4389c3b1252df0954fe1621289de25ca7618fce8 Mon Sep 17 00:00:00 2001
From: Erik Schierboom 
Date: Tue, 12 Jan 2021 10:11:32 +0100
Subject: [PATCH 078/102] Cleanup instructions headings

---
 exercises/concept/arrays/.docs/introduction.md                | 2 --
 exercises/concept/booleans/.docs/introduction.md              | 2 --
 .../concept/floating-point-numbers/.docs/introduction.md      | 4 ++--
 exercises/concept/instance-variables/.docs/introduction.md    | 4 ++--
 exercises/concept/lasagna/.docs/introduction.md               | 2 --
 exercises/concept/numbers/.docs/introduction.md               | 4 ++--
 exercises/concept/strings/.docs/introduction.md               | 2 --
 7 files changed, 6 insertions(+), 14 deletions(-)

diff --git a/exercises/concept/arrays/.docs/introduction.md b/exercises/concept/arrays/.docs/introduction.md
index ecba904dd2..ac17cb6f6b 100644
--- a/exercises/concept/arrays/.docs/introduction.md
+++ b/exercises/concept/arrays/.docs/introduction.md
@@ -1,5 +1,3 @@
-## arrays
-
 In Ruby, **arrays** are ordered, integer-indexed collections of any object. Array indexing starts at `0`. A negative index is assumed to be relative to the end of the array — i.e. an index of `-1` indicates the last element of the array, `-2` is the next to last element in the array, and so on.
 Ruby arrays mix in the [Enumerable module][enumerable-module], which adds several traversal and searching methods, and with the ability to sort.
 
diff --git a/exercises/concept/booleans/.docs/introduction.md b/exercises/concept/booleans/.docs/introduction.md
index 98f7446ecc..aef2c5f33d 100644
--- a/exercises/concept/booleans/.docs/introduction.md
+++ b/exercises/concept/booleans/.docs/introduction.md
@@ -1,5 +1,3 @@
-## booleans
-
 ## True and False
 
 True and false logical states are represented with `true` and `false` in Ruby. These may either be used as literals on their own, or as a result of logical or comparison methods.
diff --git a/exercises/concept/floating-point-numbers/.docs/introduction.md b/exercises/concept/floating-point-numbers/.docs/introduction.md
index a819fc438e..d295e22232 100644
--- a/exercises/concept/floating-point-numbers/.docs/introduction.md
+++ b/exercises/concept/floating-point-numbers/.docs/introduction.md
@@ -1,6 +1,6 @@
-## floating-point-numbers
+## Floating Point Numbers
 
-## loops
+## Loops
 
 A floating-point number is a number with zero or more digits behind the decimal separator. Examples are `4.0`, `0.1`, `3.14`, `-6.4` `16.984025` and `1024.0`.
 In Ruby, floating-point numbers are implemented through the [Float](https://ruby-doc.org/core-2.7.0/Float.html) class.
diff --git a/exercises/concept/instance-variables/.docs/introduction.md b/exercises/concept/instance-variables/.docs/introduction.md
index e78383db49..c80e093b47 100644
--- a/exercises/concept/instance-variables/.docs/introduction.md
+++ b/exercises/concept/instance-variables/.docs/introduction.md
@@ -1,6 +1,6 @@
-## instance-variables
+## Instance Variables
 
-## nil
+## Nil
 
 ## Object state, instance variables
 
diff --git a/exercises/concept/lasagna/.docs/introduction.md b/exercises/concept/lasagna/.docs/introduction.md
index b90f54e9d8..4808c0c153 100644
--- a/exercises/concept/lasagna/.docs/introduction.md
+++ b/exercises/concept/lasagna/.docs/introduction.md
@@ -1,5 +1,3 @@
-## basics
-
 Ruby is a dynamic [object-oriented language][object-oriented-programming]. Everything in Ruby is an [object][object].
 
 There are two primary ways to assign objects to names in Ruby - using variables or constants. Variables are always written in [snake case][snake-case]. A variable can reference different objects over its lifetime. For example, `my_first_variable` can be defined and redefined many times using the `=` operator:
diff --git a/exercises/concept/numbers/.docs/introduction.md b/exercises/concept/numbers/.docs/introduction.md
index 0de8e08e77..86588046a0 100644
--- a/exercises/concept/numbers/.docs/introduction.md
+++ b/exercises/concept/numbers/.docs/introduction.md
@@ -1,6 +1,6 @@
-## numbers
+## Numbers
 
-## conditionals
+## Conditionals
 
 Two common types of numbers in Ruby are:
 
diff --git a/exercises/concept/strings/.docs/introduction.md b/exercises/concept/strings/.docs/introduction.md
index 62530bdcd4..b2515ab7bf 100644
--- a/exercises/concept/strings/.docs/introduction.md
+++ b/exercises/concept/strings/.docs/introduction.md
@@ -1,3 +1 @@
-## strings
-
 A `String` in Ruby is an object that holds and manipulates an arbitrary sequence of bytes, typically representing characters. Strings are manipulated by calling the string's methods.

From 4a7c55dd3c2821f69cf57cf5a4a3d71d993de56e Mon Sep 17 00:00:00 2001
From: Daniel Wojnar 
Date: Wed, 27 Jan 2021 06:36:20 +0100
Subject: [PATCH 079/102] Remove if/else/unless from booleans concept.

* fix(booleans): remove if/else unless from concept
* prettier, update name of exercise

Co-authored-by: Tim Austin 
---
 concepts/booleans/about.md                    | 22 +------
 .../.docs/hints.md                            |  0
 .../.docs/instructions.md                     |  0
 .../.docs/introduction.md                     | 30 ++++++++++
 .../.meta/config.json                         |  4 ++
 .../.meta/design.md                           |  1 +
 .../.meta/example.rb                          |  0
 .../attendee.rb                               |  0
 .../attendee_test.rb                          |  0
 .../concept/booleans/.docs/introduction.md    | 60 -------------------
 10 files changed, 36 insertions(+), 81 deletions(-)
 rename exercises/concept/{booleans => amusement-park-rides}/.docs/hints.md (100%)
 rename exercises/concept/{booleans => amusement-park-rides}/.docs/instructions.md (100%)
 create mode 100644 exercises/concept/amusement-park-rides/.docs/introduction.md
 rename exercises/concept/{booleans => amusement-park-rides}/.meta/config.json (79%)
 rename exercises/concept/{booleans => amusement-park-rides}/.meta/design.md (99%)
 rename exercises/concept/{booleans => amusement-park-rides}/.meta/example.rb (100%)
 rename exercises/concept/{booleans => amusement-park-rides}/attendee.rb (100%)
 rename exercises/concept/{booleans => amusement-park-rides}/attendee_test.rb (100%)
 delete mode 100644 exercises/concept/booleans/.docs/introduction.md

diff --git a/concepts/booleans/about.md b/concepts/booleans/about.md
index f890230093..ccaf2fcd76 100644
--- a/concepts/booleans/about.md
+++ b/concepts/booleans/about.md
@@ -22,28 +22,8 @@
   end
   ```
 
-- It is common to use _truthy_ and _falsey_ values to determine the outcome of [conditional statements][control-expressions].
-
-  - `if`…`else` exists as a construct, similar to the [_C-family_ of programming languages][c-family]
-  - it is often more idiomatic to use `if` and `unless` as [expression modifiers to "guard" an expression][if-modifier]
-
-  ```ruby
-  1 + 1 if truthy
-  # => this will evaluate and return 2
-
-  2 + 2 if falsey
-  # => the numbers are not added because of the modifier, nil is returned
-
-  3 + 3 unless truthy
-  # => the numbers are not added because of the modifier, nil is returned
-
-  4 + 4 unless falsey
-  # => this will evaluate and return 8
-  ```
-
 [c-family]: https://en.wikipedia.org/wiki/List_of_C-family_programming_languages
-[control-expressions]: https://docs.ruby-lang.org/en/master/syntax/control_expressions_rdoc.html
-[if-modifier]: https://docs.ruby-lang.org/en/master/syntax/control_expressions_rdoc.html#label-Modifier+if+and+unless
+[control-expressions]: https://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Control_Structures
 [true-class]: https://docs.ruby-lang.org/en/master/TrueClass.html
 [false-class]: https://docs.ruby-lang.org/en/master/FalseClass.html
 [nil-class]: https://docs.ruby-lang.org/en/master/NilClass.html
diff --git a/exercises/concept/booleans/.docs/hints.md b/exercises/concept/amusement-park-rides/.docs/hints.md
similarity index 100%
rename from exercises/concept/booleans/.docs/hints.md
rename to exercises/concept/amusement-park-rides/.docs/hints.md
diff --git a/exercises/concept/booleans/.docs/instructions.md b/exercises/concept/amusement-park-rides/.docs/instructions.md
similarity index 100%
rename from exercises/concept/booleans/.docs/instructions.md
rename to exercises/concept/amusement-park-rides/.docs/instructions.md
diff --git a/exercises/concept/amusement-park-rides/.docs/introduction.md b/exercises/concept/amusement-park-rides/.docs/introduction.md
new file mode 100644
index 0000000000..15134a787f
--- /dev/null
+++ b/exercises/concept/amusement-park-rides/.docs/introduction.md
@@ -0,0 +1,30 @@
+## True and False
+
+True and false logical states are represented with `true` and `false` in Ruby. These may either be used as literals on their own, or as a result of logical or comparison methods.
+
+```ruby
+happy = true
+sad = false
+
+true && false
+# => false
+
+1 < 2
+# => true
+```
+
+## _Truthy_ and _falsey_
+
+When evaluating objects in `if` statements or other boolean contexts, all objects evaluate as _truthy_ **except** for `false` and `nil`.
+
+```ruby
+def falsey
+  nil || false
+end
+
+def truthy
+  not falsey
+end
+```
+
+[nil-dictionary]: https://www.merriam-webster.com/dictionary/nil
diff --git a/exercises/concept/booleans/.meta/config.json b/exercises/concept/amusement-park-rides/.meta/config.json
similarity index 79%
rename from exercises/concept/booleans/.meta/config.json
rename to exercises/concept/amusement-park-rides/.meta/config.json
index 8c14b3557c..887749e433 100644
--- a/exercises/concept/booleans/.meta/config.json
+++ b/exercises/concept/amusement-park-rides/.meta/config.json
@@ -13,6 +13,10 @@
     {
       "github_username": "iHiD",
       "exercism_username": "iHiD"
+    },
+    {
+      "github_username": "kayn1",
+      "exercism_username": "kayn1"
     }
   ],
   "language_versions": ">=2.6.6"
diff --git a/exercises/concept/booleans/.meta/design.md b/exercises/concept/amusement-park-rides/.meta/design.md
similarity index 99%
rename from exercises/concept/booleans/.meta/design.md
rename to exercises/concept/amusement-park-rides/.meta/design.md
index 7467e78dd0..5ff6515da7 100644
--- a/exercises/concept/booleans/.meta/design.md
+++ b/exercises/concept/amusement-park-rides/.meta/design.md
@@ -28,6 +28,7 @@ The goal of this exercise is to teach the student the basics of the Concept of "
 ## Prerequisites
 
 - `basics`
+- `numbers`
 
 ## Resources
 
diff --git a/exercises/concept/booleans/.meta/example.rb b/exercises/concept/amusement-park-rides/.meta/example.rb
similarity index 100%
rename from exercises/concept/booleans/.meta/example.rb
rename to exercises/concept/amusement-park-rides/.meta/example.rb
diff --git a/exercises/concept/booleans/attendee.rb b/exercises/concept/amusement-park-rides/attendee.rb
similarity index 100%
rename from exercises/concept/booleans/attendee.rb
rename to exercises/concept/amusement-park-rides/attendee.rb
diff --git a/exercises/concept/booleans/attendee_test.rb b/exercises/concept/amusement-park-rides/attendee_test.rb
similarity index 100%
rename from exercises/concept/booleans/attendee_test.rb
rename to exercises/concept/amusement-park-rides/attendee_test.rb
diff --git a/exercises/concept/booleans/.docs/introduction.md b/exercises/concept/booleans/.docs/introduction.md
deleted file mode 100644
index aef2c5f33d..0000000000
--- a/exercises/concept/booleans/.docs/introduction.md
+++ /dev/null
@@ -1,60 +0,0 @@
-## True and False
-
-True and false logical states are represented with `true` and `false` in Ruby. These may either be used as literals on their own, or as a result of logical or comparison methods.
-
-```ruby
-happy = true
-sad = false
-
-true && false
-# => false
-
-1 < 2
-# => true
-```
-
-## _Truthy_ and _falsey_
-
-When evaluating objects in `if` statements or other boolean contexts, all objects evaluate as _truthy_ **except** for `false` and `nil`.
-
-## Control flow
-
-_Truthy_ and _falsey_ evaluations are useful in the context of control flow. Like in procedural languages, Ruby has an `if`...`else` construct, but it may be more common to use `if` as a "guarding" statement to modify the evaluation of an expression.
-
-```ruby
-def falsey
-  nil || false
-end
-
-def truthy
-  not falsey
-end
-
-if truthy
-  # this block is evaluated
-end
-
-if falsey
-  # this block is not evaluated
-else
-  # this block is evaluated
-end
-
-1 + 1 if truthy
-# => this will evaluate and return 2
-
-2 + 2 if falsey
-# => the numbers are not added because of the modifier, nil is returned
-```
-
-Ruby provides `unless` to make code read well. E.g.) Rather than `eat_desert if not too_full`, we can also write `eat_desert unless too_full`.
-
-```ruby
-3 + 3 unless truthy
-# => the numbers are not added because of the modifier, nil is returned
-
-4 + 4 unless falsey
-# => this will evaluate and return 8
-```
-
-[nil-dictionary]: https://www.merriam-webster.com/dictionary/nil

From 64406a8adde5b6a9f839d0d9d1f161eefda9989b Mon Sep 17 00:00:00 2001
From: Alex <19227912+lxmrc@users.noreply.github.com>
Date: Wed, 27 Jan 2021 17:34:48 +1100
Subject: [PATCH 080/102] Implement new Concept Exercise: conditionals-ternary
 #1903

* Implement new Concept Exercise: conditionals-ternary #1903

* Use American English

* [CI] Format code

Co-authored-by: github-actions[bot] 
---
 .../.docs/instructions.md                     | 39 +++++++++++++++++++
 .../.docs/introduction.md                     | 21 ++++++++++
 .../conditionals-ternary/.meta/example.rb     | 22 +++++++++++
 .../concept/conditionals-ternary/moviegoer.rb | 22 +++++++++++
 .../conditionals-ternary/moviegoer_test.rb    | 34 ++++++++++++++++
 5 files changed, 138 insertions(+)
 create mode 100644 exercises/concept/conditionals-ternary/.docs/instructions.md
 create mode 100644 exercises/concept/conditionals-ternary/.docs/introduction.md
 create mode 100644 exercises/concept/conditionals-ternary/.meta/example.rb
 create mode 100644 exercises/concept/conditionals-ternary/moviegoer.rb
 create mode 100644 exercises/concept/conditionals-ternary/moviegoer_test.rb

diff --git a/exercises/concept/conditionals-ternary/.docs/instructions.md b/exercises/concept/conditionals-ternary/.docs/instructions.md
new file mode 100644
index 0000000000..28831b385c
--- /dev/null
+++ b/exercises/concept/conditionals-ternary/.docs/instructions.md
@@ -0,0 +1,39 @@
+In this exercise you will rewrite `if/else` statements from a movie theater's website into ternary conditionals.
+
+## 1. Check if a moviegoer is entitled to the seniors' discount
+
+Rewrite the `Moviegoer#ticket_price` method to utilize the ternary operator.
+
+```ruby
+  def ticket_price
+    if age < 60
+      15
+    else
+      10
+    end
+  end
+```
+
+## 2. Check if a moviegoer is allowed to see scary movies
+
+```ruby
+  def watch_scary_movie
+    if age >= 18
+      "Enjoy the movie!"
+    else
+      "You must be over 18 to see this movie."
+    end
+  end
+```
+
+## 3. Check if a moviegoer is entitled to free popcorn
+
+```ruby
+  def claim_free_popcorn
+    if movie_club_member
+      "Enjoy your free popcorn!"
+    else
+      "Join the Movie Club to get free popcorn."
+    end
+  end
+```
diff --git a/exercises/concept/conditionals-ternary/.docs/introduction.md b/exercises/concept/conditionals-ternary/.docs/introduction.md
new file mode 100644
index 0000000000..220dce4dc1
--- /dev/null
+++ b/exercises/concept/conditionals-ternary/.docs/introduction.md
@@ -0,0 +1,21 @@
+A ternary conditional in Ruby is a shorter way of writing simple `if/else` statements. If an `if/else` statement contains only two branches, one for when the condition is true and one for when it is false, it can be re-written as a ternary conditional.
+
+It uses a combination of the `?` and `:` symbols, often called the ternary operator(s).
+
+For example:
+
+```ruby
+if traffic_light == 'green'
+  cross_the_road
+else
+  wait
+end
+```
+
+can be re-written as:
+
+```ruby
+traffic_light == 'green' ? cross_the_road : wait
+```
+
+The code on the left side of the `?` is the condition and the code on the right contains the two possible branches, separated by the `:`. If the condition is _true_, the code on the _left_ side of the `:` is executed; if the condition is _false_, then the code on the _right_ of the `:` gets executed.
diff --git a/exercises/concept/conditionals-ternary/.meta/example.rb b/exercises/concept/conditionals-ternary/.meta/example.rb
new file mode 100644
index 0000000000..b20bb2087a
--- /dev/null
+++ b/exercises/concept/conditionals-ternary/.meta/example.rb
@@ -0,0 +1,22 @@
+class Moviegoer
+  attr_reader :age, :movie_club_member
+
+  def initialize(age, movie_club_member: false)
+    @age = age
+    @movie_club_member = movie_club_member
+  end
+
+  # Do not edit above methods, add your own methods below.
+  
+  def ticket_price
+    age < 60 ? 15 : 10
+  end
+
+  def watch_scary_movie
+    age >= 18 ? "Enjoy the movie!" : "You must be over 18 to see this movie."
+  end
+
+  def claim_free_popcorn
+    movie_club_member ? "Enjoy your free popcorn!" : "Join the Movie Club to get free popcorn."
+  end
+end
diff --git a/exercises/concept/conditionals-ternary/moviegoer.rb b/exercises/concept/conditionals-ternary/moviegoer.rb
new file mode 100644
index 0000000000..a770d280d1
--- /dev/null
+++ b/exercises/concept/conditionals-ternary/moviegoer.rb
@@ -0,0 +1,22 @@
+class Moviegoer
+  attr_reader :age, :movie_club_member
+
+  def initialize(age, movie_club_member: false)
+    @age = age
+    @movie_club_member = movie_club_member
+  end
+
+  # Do not edit above methods, add your own methods below.
+  
+  def ticket_price
+    raise NotImplementedError, 'Please implement the Moviegoer#ticket_price method'
+  end
+
+  def watch_scary_movie
+    raise NotImplementedError, 'Please implement the Moviegoer#watch_scary_movie method'
+  end
+
+  def claim_free_popcorn
+    raise NotImplementedError, 'Please implement the Moviegoer#claim_free_popcorn method'
+  end
+end
diff --git a/exercises/concept/conditionals-ternary/moviegoer_test.rb b/exercises/concept/conditionals-ternary/moviegoer_test.rb
new file mode 100644
index 0000000000..bab7ffda21
--- /dev/null
+++ b/exercises/concept/conditionals-ternary/moviegoer_test.rb
@@ -0,0 +1,34 @@
+require 'minitest/autorun'
+require_relative 'moviegoer'
+
+class MoviegoerTest < Minitest::Test
+  def test_regular_ticket_price
+    moviegoer = Moviegoer.new(25)
+    assert_equal 15, moviegoer.ticket_price
+  end
+
+  def test_seniors_discount
+    moviegoer = Moviegoer.new(60)
+    assert_equal 10, moviegoer.ticket_price
+  end
+
+  def test_adults_can_see_the_scary_movie
+    moviegoer = Moviegoer.new(25)
+    assert_equal "Enjoy the movie!", moviegoer.watch_scary_movie
+  end
+
+  def test_kids_cant_see_the_scary_movie
+    moviegoer = Moviegoer.new(10)
+    assert_equal "You must be over 18 to see this movie.", moviegoer.watch_scary_movie
+  end
+
+  def test_movie_club_members_get_free_popcorn
+    moviegoer = Moviegoer.new(25, movie_club_member: true)
+    assert_equal "Enjoy your free popcorn!", moviegoer.claim_free_popcorn
+  end
+
+  def test_regular_moviegoers_dont_get_free_popcorn
+    moviegoer = Moviegoer.new(25)
+    assert_equal "Join the Movie Club to get free popcorn.", moviegoer.claim_free_popcorn
+  end
+end

From ef33529fe09ec8e4be0aad913d0c4100c92a5cd3 Mon Sep 17 00:00:00 2001
From: Erik Schierboom 
Date: Thu, 28 Jan 2021 14:12:05 +0100
Subject: [PATCH 081/102] Convert example to exemplar

* Rename example files to exemplar

See https://github.com/exercism/v3-docs/pull/23

* [Docs] Correct .meta/example references to .meta/exemplar

* [Docs] Use exemplar instead of example

* [Docs] Update example name in file listings

* [Julia] Convert to exemplar.jl

* [elm] Rename .meta/Cook.elm to .meta/Examplar.elm

* [elm] Rename .meta/Examplar.elm .meta/Exemplar.elm

Co-authored-by: Matthieu Pizenberg 
---
 .../amusement-park-rides/.meta/{example.rb => exemplar.rb}    | 0
 exercises/concept/arrays/.meta/{example.rb => exemplar.rb}    | 0
 .../conditionals-ternary/.meta/{example.rb => exemplar.rb}    | 0
 .../concept/exceptions/.meta/{example.rb => exemplar.rb}      | 0
 .../floating-point-numbers/.meta/{example.rb => exemplar.rb}  | 0
 .../instance-variables/.meta/{example.rb => exemplar.rb}      | 0
 exercises/concept/lasagna/.meta/{example.rb => exemplar.rb}   | 0
 exercises/concept/numbers/.meta/{example.rb => exemplar.rb}   | 0
 exercises/concept/strings/.meta/{example.rb => exemplar.rb}   | 0
 reference/implementing-a-concept-exercise.md                  | 4 ++--
 10 files changed, 2 insertions(+), 2 deletions(-)
 rename exercises/concept/amusement-park-rides/.meta/{example.rb => exemplar.rb} (100%)
 rename exercises/concept/arrays/.meta/{example.rb => exemplar.rb} (100%)
 rename exercises/concept/conditionals-ternary/.meta/{example.rb => exemplar.rb} (100%)
 rename exercises/concept/exceptions/.meta/{example.rb => exemplar.rb} (100%)
 rename exercises/concept/floating-point-numbers/.meta/{example.rb => exemplar.rb} (100%)
 rename exercises/concept/instance-variables/.meta/{example.rb => exemplar.rb} (100%)
 rename exercises/concept/lasagna/.meta/{example.rb => exemplar.rb} (100%)
 rename exercises/concept/numbers/.meta/{example.rb => exemplar.rb} (100%)
 rename exercises/concept/strings/.meta/{example.rb => exemplar.rb} (100%)

diff --git a/exercises/concept/amusement-park-rides/.meta/example.rb b/exercises/concept/amusement-park-rides/.meta/exemplar.rb
similarity index 100%
rename from exercises/concept/amusement-park-rides/.meta/example.rb
rename to exercises/concept/amusement-park-rides/.meta/exemplar.rb
diff --git a/exercises/concept/arrays/.meta/example.rb b/exercises/concept/arrays/.meta/exemplar.rb
similarity index 100%
rename from exercises/concept/arrays/.meta/example.rb
rename to exercises/concept/arrays/.meta/exemplar.rb
diff --git a/exercises/concept/conditionals-ternary/.meta/example.rb b/exercises/concept/conditionals-ternary/.meta/exemplar.rb
similarity index 100%
rename from exercises/concept/conditionals-ternary/.meta/example.rb
rename to exercises/concept/conditionals-ternary/.meta/exemplar.rb
diff --git a/exercises/concept/exceptions/.meta/example.rb b/exercises/concept/exceptions/.meta/exemplar.rb
similarity index 100%
rename from exercises/concept/exceptions/.meta/example.rb
rename to exercises/concept/exceptions/.meta/exemplar.rb
diff --git a/exercises/concept/floating-point-numbers/.meta/example.rb b/exercises/concept/floating-point-numbers/.meta/exemplar.rb
similarity index 100%
rename from exercises/concept/floating-point-numbers/.meta/example.rb
rename to exercises/concept/floating-point-numbers/.meta/exemplar.rb
diff --git a/exercises/concept/instance-variables/.meta/example.rb b/exercises/concept/instance-variables/.meta/exemplar.rb
similarity index 100%
rename from exercises/concept/instance-variables/.meta/example.rb
rename to exercises/concept/instance-variables/.meta/exemplar.rb
diff --git a/exercises/concept/lasagna/.meta/example.rb b/exercises/concept/lasagna/.meta/exemplar.rb
similarity index 100%
rename from exercises/concept/lasagna/.meta/example.rb
rename to exercises/concept/lasagna/.meta/exemplar.rb
diff --git a/exercises/concept/numbers/.meta/example.rb b/exercises/concept/numbers/.meta/exemplar.rb
similarity index 100%
rename from exercises/concept/numbers/.meta/example.rb
rename to exercises/concept/numbers/.meta/exemplar.rb
diff --git a/exercises/concept/strings/.meta/example.rb b/exercises/concept/strings/.meta/exemplar.rb
similarity index 100%
rename from exercises/concept/strings/.meta/example.rb
rename to exercises/concept/strings/.meta/exemplar.rb
diff --git a/reference/implementing-a-concept-exercise.md b/reference/implementing-a-concept-exercise.md
index 5f4c71feca..a481cd627e 100644
--- a/reference/implementing-a-concept-exercise.md
+++ b/reference/implementing-a-concept-exercise.md
@@ -36,7 +36,7 @@ languages
                 ├── .meta
                 |   |── config.json
                 |   |── design.md
-                |   └── example.rb
+                |   └── exemplar.rb
                 ├── .rb
                 └── _test.rb
 
@@ -47,7 +47,7 @@ The code files are track-specific and should be designed to help the student lea - `.rb`. the stub implementation file, which is the starting point for students to work on the exercise. - `_test.rb`: the test suite. -- `.meta/example.rb`: an example implementation that passes all the tests. +- `.meta/exemplar.rb`: an exemplar implementation that passes all the tests. ## Step 2: Add documentation files From ee902030a9d62b233e6f79e86dd406fa6f156bcd Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 08:37:42 +0100 Subject: [PATCH 082/102] Convert editor key in .meta/config.json files * Convert editor key to files * Add missing "files" field to .meta/config.json files * Add exemplar files to .meta/config.json * Add common-lisp exemplar to template --- exercises/concept/amusement-park-rides/.meta/config.json | 7 ++++++- exercises/concept/arrays/.meta/config.json | 7 ++++++- exercises/concept/exceptions/.meta/config.json | 7 ++++++- exercises/concept/floating-point-numbers/.meta/config.json | 7 ++++++- exercises/concept/instance-variables/.meta/config.json | 7 ++++++- exercises/concept/lasagna/.meta/config.json | 7 ++++--- exercises/concept/numbers/.meta/config.json | 7 ++++++- exercises/concept/strings/.meta/config.json | 7 ++++++- 8 files changed, 46 insertions(+), 10 deletions(-) diff --git a/exercises/concept/amusement-park-rides/.meta/config.json b/exercises/concept/amusement-park-rides/.meta/config.json index 887749e433..e9bbfa3844 100644 --- a/exercises/concept/amusement-park-rides/.meta/config.json +++ b/exercises/concept/amusement-park-rides/.meta/config.json @@ -19,5 +19,10 @@ "exercism_username": "kayn1" } ], - "language_versions": ">=2.6.6" + "language_versions": ">=2.6.6", + "files": { + "solution": [], + "test": [], + "exemplar": [".meta/exemplar.rb"] + } } diff --git a/exercises/concept/arrays/.meta/config.json b/exercises/concept/arrays/.meta/config.json index 827e937cbe..5aea4614fe 100644 --- a/exercises/concept/arrays/.meta/config.json +++ b/exercises/concept/arrays/.meta/config.json @@ -5,5 +5,10 @@ "exercism_username": "pvcarrera" } ], - "forked_from": ["csharp/arrays"] + "forked_from": ["csharp/arrays"], + "files": { + "solution": [], + "test": [], + "exemplar": [".meta/exemplar.rb"] + } } diff --git a/exercises/concept/exceptions/.meta/config.json b/exercises/concept/exceptions/.meta/config.json index 1d9a6cd3f7..fb09e4edab 100644 --- a/exercises/concept/exceptions/.meta/config.json +++ b/exercises/concept/exceptions/.meta/config.json @@ -5,5 +5,10 @@ "exercism_username": "pvcarrera" } ], - "forked_from": ["csharp/exceptions"] + "forked_from": ["csharp/exceptions"], + "files": { + "solution": [], + "test": [], + "exemplar": [".meta/exemplar.rb"] + } } diff --git a/exercises/concept/floating-point-numbers/.meta/config.json b/exercises/concept/floating-point-numbers/.meta/config.json index 3afe01e988..0dfdd2ac30 100644 --- a/exercises/concept/floating-point-numbers/.meta/config.json +++ b/exercises/concept/floating-point-numbers/.meta/config.json @@ -5,5 +5,10 @@ "exercism_username": "dvik1950" } ], - "forked_from": ["csharp/floating-point-numbers"] + "forked_from": ["csharp/floating-point-numbers"], + "files": { + "solution": [], + "test": [], + "exemplar": [".meta/exemplar.rb"] + } } diff --git a/exercises/concept/instance-variables/.meta/config.json b/exercises/concept/instance-variables/.meta/config.json index 9771b33b79..5ed7acc579 100644 --- a/exercises/concept/instance-variables/.meta/config.json +++ b/exercises/concept/instance-variables/.meta/config.json @@ -15,5 +15,10 @@ "exercism_username": "kotp" } ], - "language_versions": ">=2.6.6" + "language_versions": ">=2.6.6", + "files": { + "solution": [], + "test": [], + "exemplar": [".meta/exemplar.rb"] + } } diff --git a/exercises/concept/lasagna/.meta/config.json b/exercises/concept/lasagna/.meta/config.json index 5b9e1717dc..a86dec3861 100644 --- a/exercises/concept/lasagna/.meta/config.json +++ b/exercises/concept/lasagna/.meta/config.json @@ -9,8 +9,9 @@ "exercism_username": "pvcarrera" } ], - "editor": { - "solution_files": ["lasagna.rb"], - "test_files": ["lasagna_test.rb"] + "files": { + "solution": ["lasagna.rb"], + "test": ["lasagna_test.rb"], + "exemplar": [".meta/exemplar.rb"] } } diff --git a/exercises/concept/numbers/.meta/config.json b/exercises/concept/numbers/.meta/config.json index f2f5a942e5..5eb16a15e1 100644 --- a/exercises/concept/numbers/.meta/config.json +++ b/exercises/concept/numbers/.meta/config.json @@ -15,5 +15,10 @@ "exercism_username": "iHiD" } ], - "forked_from": ["csharp/numbers"] + "forked_from": ["csharp/numbers"], + "files": { + "solution": [], + "test": [], + "exemplar": [".meta/exemplar.rb"] + } } diff --git a/exercises/concept/strings/.meta/config.json b/exercises/concept/strings/.meta/config.json index db52a259fb..f97639477d 100644 --- a/exercises/concept/strings/.meta/config.json +++ b/exercises/concept/strings/.meta/config.json @@ -4,5 +4,10 @@ "github_username": "pvcarrera", "exercism_username": "pvcarrera" } - ] + ], + "files": { + "solution": [], + "test": [], + "exemplar": [".meta/exemplar.rb"] + } } From bf884095fbcdb0ed5c874553fd3c1c49c827c9c4 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:44 +0100 Subject: [PATCH 083/102] [v3] Move existing exercises to exercises/practice --- exercises/{ => practice}/accumulate/.meta/hints.md | 0 exercises/{ => practice}/accumulate/.meta/solutions/accumulate.rb | 0 exercises/{ => practice}/accumulate/README.md | 0 exercises/{ => practice}/accumulate/accumulate.rb | 0 exercises/{ => practice}/accumulate/accumulate_test.rb | 0 exercises/{ => practice}/acronym/.meta/generator/acronym_case.rb | 0 exercises/{ => practice}/acronym/.meta/solutions/acronym.rb | 0 exercises/{ => practice}/acronym/.meta/tests.toml | 0 exercises/{ => practice}/acronym/README.md | 0 exercises/{ => practice}/acronym/acronym.rb | 0 exercises/{ => practice}/acronym/acronym_test.rb | 0 .../affine-cipher/.meta/generator/affine_cipher_case.rb | 0 .../{ => practice}/affine-cipher/.meta/solutions/affine_cipher.rb | 0 exercises/{ => practice}/affine-cipher/.meta/tests.toml | 0 exercises/{ => practice}/affine-cipher/README.md | 0 exercises/{ => practice}/affine-cipher/affine_cipher.rb | 0 exercises/{ => practice}/affine-cipher/affine_cipher_test.rb | 0 .../all-your-base/.meta/generator/all_your_base_case.rb | 0 .../{ => practice}/all-your-base/.meta/solutions/all_your_base.rb | 0 exercises/{ => practice}/all-your-base/.meta/tests.toml | 0 exercises/{ => practice}/all-your-base/README.md | 0 exercises/{ => practice}/all-your-base/all_your_base.rb | 0 exercises/{ => practice}/all-your-base/all_your_base_test.rb | 0 .../{ => practice}/allergies/.meta/generator/allergies_case.rb | 0 exercises/{ => practice}/allergies/.meta/solutions/allergies.rb | 0 exercises/{ => practice}/allergies/.meta/tests.toml | 0 exercises/{ => practice}/allergies/README.md | 0 exercises/{ => practice}/allergies/allergies.rb | 0 exercises/{ => practice}/allergies/allergies_test.rb | 0 .../alphametics/.meta/generator/alphametics_case.rb | 0 .../{ => practice}/alphametics/.meta/solutions/alphametics.rb | 0 .../alphametics/.meta/solutions/alphametics_compact.rb | 0 exercises/{ => practice}/alphametics/.meta/tests.toml | 0 exercises/{ => practice}/alphametics/README.md | 0 exercises/{ => practice}/alphametics/alphametics.rb | 0 exercises/{ => practice}/alphametics/alphametics_test.rb | 0 exercises/{ => practice}/anagram/.meta/generator/anagram_case.rb | 0 exercises/{ => practice}/anagram/.meta/solutions/anagram.rb | 0 exercises/{ => practice}/anagram/.meta/tests.toml | 0 exercises/{ => practice}/anagram/README.md | 0 exercises/{ => practice}/anagram/anagram.rb | 0 exercises/{ => practice}/anagram/anagram_test.rb | 0 .../armstrong-numbers/.meta/generator/armstrong_numbers_case.rb | 0 .../armstrong-numbers/.meta/solutions/armstrong_numbers.rb | 0 exercises/{ => practice}/armstrong-numbers/.meta/tests.toml | 0 exercises/{ => practice}/armstrong-numbers/README.md | 0 exercises/{ => practice}/armstrong-numbers/armstrong_numbers.rb | 0 .../{ => practice}/armstrong-numbers/armstrong_numbers_test.rb | 0 .../atbash-cipher/.meta/generator/atbash_cipher_case.rb | 0 .../{ => practice}/atbash-cipher/.meta/solutions/atbash_cipher.rb | 0 exercises/{ => practice}/atbash-cipher/.meta/tests.toml | 0 exercises/{ => practice}/atbash-cipher/README.md | 0 exercises/{ => practice}/atbash-cipher/atbash_cipher.rb | 0 exercises/{ => practice}/atbash-cipher/atbash_cipher_test.rb | 0 .../{ => practice}/beer-song/.meta/generator/beer_song_case.rb | 0 exercises/{ => practice}/beer-song/.meta/solutions/beer_song.rb | 0 exercises/{ => practice}/beer-song/.meta/tests.toml | 0 exercises/{ => practice}/beer-song/README.md | 0 exercises/{ => practice}/beer-song/beer_song.rb | 0 exercises/{ => practice}/beer-song/beer_song_test.rb | 0 .../binary-search-tree/.meta/solutions/binary_search_tree.rb | 0 exercises/{ => practice}/binary-search-tree/.meta/tests.toml | 0 exercises/{ => practice}/binary-search-tree/README.md | 0 exercises/{ => practice}/binary-search-tree/binary_search_tree.rb | 0 .../{ => practice}/binary-search-tree/binary_search_tree_test.rb | 0 .../binary-search/.meta/generator/binary_search_case.rb | 0 .../{ => practice}/binary-search/.meta/solutions/binary_search.rb | 0 exercises/{ => practice}/binary-search/.meta/tests.toml | 0 exercises/{ => practice}/binary-search/README.md | 0 exercises/{ => practice}/binary-search/binary_search.rb | 0 exercises/{ => practice}/binary-search/binary_search_test.rb | 0 exercises/{ => practice}/binary/.meta/generator/binary_case.rb | 0 exercises/{ => practice}/binary/.meta/solutions/binary.rb | 0 exercises/{ => practice}/binary/.meta/tests.toml | 0 exercises/{ => practice}/binary/README.md | 0 exercises/{ => practice}/binary/binary.rb | 0 exercises/{ => practice}/binary/binary_test.rb | 0 exercises/{ => practice}/bob/.meta/generator/bob_case.rb | 0 exercises/{ => practice}/bob/.meta/solutions/bob.rb | 0 exercises/{ => practice}/bob/.meta/tests.toml | 0 exercises/{ => practice}/bob/README.md | 0 exercises/{ => practice}/bob/bob.rb | 0 exercises/{ => practice}/bob/bob_test.rb | 0 .../{ => practice}/book-store/.meta/generator/book_store_case.rb | 0 exercises/{ => practice}/book-store/.meta/solutions/book_store.rb | 0 exercises/{ => practice}/book-store/.meta/tests.toml | 0 exercises/{ => practice}/book-store/README.md | 0 exercises/{ => practice}/book-store/book_store.rb | 0 exercises/{ => practice}/book-store/book_store_test.rb | 0 exercises/{ => practice}/bowling/.meta/generator/bowling_case.rb | 0 exercises/{ => practice}/bowling/.meta/solutions/bowling.rb | 0 exercises/{ => practice}/bowling/.meta/tests.toml | 0 exercises/{ => practice}/bowling/README.md | 0 exercises/{ => practice}/bowling/bowling.rb | 0 exercises/{ => practice}/bowling/bowling_test.rb | 0 exercises/{ => practice}/change/.meta/generator/change_case.rb | 0 exercises/{ => practice}/change/.meta/solutions/change.rb | 0 exercises/{ => practice}/change/.meta/tests.toml | 0 exercises/{ => practice}/change/README.md | 0 exercises/{ => practice}/change/change.rb | 0 exercises/{ => practice}/change/change_test.rb | 0 .../circular-buffer/.meta/solutions/circular_buffer.rb | 0 exercises/{ => practice}/circular-buffer/.meta/tests.toml | 0 exercises/{ => practice}/circular-buffer/README.md | 0 exercises/{ => practice}/circular-buffer/circular_buffer.rb | 0 exercises/{ => practice}/circular-buffer/circular_buffer_test.rb | 0 exercises/{ => practice}/clock/.meta/generator/clock_case.rb | 0 exercises/{ => practice}/clock/.meta/solutions/clock.rb | 0 exercises/{ => practice}/clock/.meta/tests.toml | 0 exercises/{ => practice}/clock/README.md | 0 exercises/{ => practice}/clock/clock.rb | 0 exercises/{ => practice}/clock/clock_test.rb | 0 .../collatz-conjecture/.meta/generator/collatz_conjecture_case.rb | 0 .../collatz-conjecture/.meta/solutions/collatz_conjecture.rb | 0 exercises/{ => practice}/collatz-conjecture/.meta/tests.toml | 0 exercises/{ => practice}/collatz-conjecture/README.md | 0 exercises/{ => practice}/collatz-conjecture/collatz_conjecture.rb | 0 .../{ => practice}/collatz-conjecture/collatz_conjecture_test.rb | 0 .../complex-numbers/.meta/generator/complex_numbers_case.rb | 0 .../complex-numbers/.meta/solutions/complex_numbers.rb | 0 exercises/{ => practice}/complex-numbers/.meta/tests.toml | 0 exercises/{ => practice}/complex-numbers/README.md | 0 exercises/{ => practice}/complex-numbers/complex_numbers.rb | 0 exercises/{ => practice}/complex-numbers/complex_numbers_test.rb | 0 exercises/{ => practice}/connect/.meta/generator/connect_case.rb | 0 exercises/{ => practice}/connect/.meta/solutions/connect.rb | 0 exercises/{ => practice}/connect/.meta/tests.toml | 0 exercises/{ => practice}/connect/README.md | 0 exercises/{ => practice}/connect/connect.rb | 0 exercises/{ => practice}/connect/connect_test.rb | 0 .../crypto-square/.meta/generator/crypto_square_case.rb | 0 .../{ => practice}/crypto-square/.meta/solutions/crypto_square.rb | 0 exercises/{ => practice}/crypto-square/.meta/tests.toml | 0 exercises/{ => practice}/crypto-square/README.md | 0 exercises/{ => practice}/crypto-square/crypto_square.rb | 0 exercises/{ => practice}/crypto-square/crypto_square_test.rb | 0 .../{ => practice}/custom-set/.meta/generator/custom_set_case.rb | 0 exercises/{ => practice}/custom-set/.meta/solutions/custom_set.rb | 0 exercises/{ => practice}/custom-set/.meta/tests.toml | 0 exercises/{ => practice}/custom-set/README.md | 0 exercises/{ => practice}/custom-set/custom_set.rb | 0 exercises/{ => practice}/custom-set/custom_set_test.rb | 0 exercises/{ => practice}/darts/.meta/generator/darts_case.rb | 0 exercises/{ => practice}/darts/.meta/solutions/darts.rb | 0 exercises/{ => practice}/darts/.meta/tests.toml | 0 exercises/{ => practice}/darts/README.md | 0 exercises/{ => practice}/darts/darts.rb | 0 exercises/{ => practice}/darts/darts_test.rb | 0 exercises/{ => practice}/diamond/.meta/solutions/diamond.rb | 0 exercises/{ => practice}/diamond/.meta/tests.toml | 0 exercises/{ => practice}/diamond/README.md | 0 exercises/{ => practice}/diamond/diamond.rb | 0 exercises/{ => practice}/diamond/diamond_test.rb | 0 .../.meta/generator/difference_of_squares_case.rb | 0 .../.meta/solutions/difference_of_squares.rb | 0 exercises/{ => practice}/difference-of-squares/.meta/tests.toml | 0 exercises/{ => practice}/difference-of-squares/README.md | 0 .../{ => practice}/difference-of-squares/difference_of_squares.rb | 0 .../difference-of-squares/difference_of_squares_test.rb | 0 .../{ => practice}/dominoes/.meta/generator/dominoes_case.rb | 0 exercises/{ => practice}/dominoes/.meta/solutions/dominoes.rb | 0 exercises/{ => practice}/dominoes/.meta/tests.toml | 0 exercises/{ => practice}/dominoes/README.md | 0 exercises/{ => practice}/dominoes/dominoes.rb | 0 exercises/{ => practice}/dominoes/dominoes_test.rb | 0 exercises/{ => practice}/etl/.meta/generator/etl_case.rb | 0 exercises/{ => practice}/etl/.meta/solutions/etl.rb | 0 exercises/{ => practice}/etl/.meta/tests.toml | 0 exercises/{ => practice}/etl/README.md | 0 exercises/{ => practice}/etl/etl.rb | 0 exercises/{ => practice}/etl/etl_test.rb | 0 .../flatten-array/.meta/generator/flatten_array_case.rb | 0 .../{ => practice}/flatten-array/.meta/solutions/flatten_array.rb | 0 exercises/{ => practice}/flatten-array/.meta/tests.toml | 0 exercises/{ => practice}/flatten-array/README.md | 0 exercises/{ => practice}/flatten-array/flatten_array.rb | 0 exercises/{ => practice}/flatten-array/flatten_array_test.rb | 0 exercises/{ => practice}/food-chain/.meta/solutions/food_chain.rb | 0 exercises/{ => practice}/food-chain/.meta/tests.toml | 0 exercises/{ => practice}/food-chain/README.md | 0 exercises/{ => practice}/food-chain/food_chain.rb | 0 exercises/{ => practice}/food-chain/food_chain_test.rb | 0 exercises/{ => practice}/food-chain/song.txt | 0 .../{ => practice}/gigasecond/.meta/generator/gigasecond_case.rb | 0 exercises/{ => practice}/gigasecond/.meta/solutions/gigasecond.rb | 0 exercises/{ => practice}/gigasecond/.meta/tests.toml | 0 exercises/{ => practice}/gigasecond/README.md | 0 exercises/{ => practice}/gigasecond/gigasecond.rb | 0 exercises/{ => practice}/gigasecond/gigasecond_test.rb | 0 .../{ => practice}/grade-school/.meta/solutions/grade_school.rb | 0 exercises/{ => practice}/grade-school/.meta/tests.toml | 0 exercises/{ => practice}/grade-school/README.md | 0 exercises/{ => practice}/grade-school/grade_school.rb | 0 exercises/{ => practice}/grade-school/grade_school_test.rb | 0 exercises/{ => practice}/grains/.meta/generator/grains_case.rb | 0 exercises/{ => practice}/grains/.meta/solutions/grains.rb | 0 exercises/{ => practice}/grains/README.md | 0 exercises/{ => practice}/grains/grains.rb | 0 exercises/{ => practice}/grains/grains_test.rb | 0 exercises/{ => practice}/grep/.meta/generator/grep_case.rb | 0 exercises/{ => practice}/grep/.meta/generator/test_template.erb | 0 exercises/{ => practice}/grep/.meta/solutions/grep.rb | 0 exercises/{ => practice}/grep/.meta/tests.toml | 0 exercises/{ => practice}/grep/README.md | 0 exercises/{ => practice}/grep/grep.rb | 0 exercises/{ => practice}/grep/grep_test.rb | 0 exercises/{ => practice}/hamming/.meta/generator/hamming_case.rb | 0 exercises/{ => practice}/hamming/.meta/solutions/hamming.rb | 0 exercises/{ => practice}/hamming/.meta/tests.toml | 0 exercises/{ => practice}/hamming/README.md | 0 exercises/{ => practice}/hamming/RUNNING_TESTS.md | 0 exercises/{ => practice}/hamming/hamming.rb | 0 exercises/{ => practice}/hamming/hamming_test.rb | 0 .../hello-world/.meta/generator/hello_world_case.rb | 0 .../{ => practice}/hello-world/.meta/generator/test_template.erb | 0 .../{ => practice}/hello-world/.meta/solutions/hello_world.rb | 0 exercises/{ => practice}/hello-world/.meta/tests.toml | 0 exercises/{ => practice}/hello-world/GETTING_STARTED.md | 0 exercises/{ => practice}/hello-world/README.md | 0 exercises/{ => practice}/hello-world/hello_world.rb | 0 exercises/{ => practice}/hello-world/hello_world_test.rb | 0 .../{ => practice}/hexadecimal/.meta/solutions/hexadecimal.rb | 0 exercises/{ => practice}/hexadecimal/README.md | 0 exercises/{ => practice}/hexadecimal/hexadecimal.rb | 0 exercises/{ => practice}/hexadecimal/hexadecimal_test.rb | 0 .../high-scores/.meta/generator/high_scores_case.rb | 0 exercises/{ => practice}/high-scores/.meta/hints.md | 0 .../{ => practice}/high-scores/.meta/solutions/high_scores.rb | 0 exercises/{ => practice}/high-scores/.meta/tests.toml | 0 exercises/{ => practice}/high-scores/README.md | 0 exercises/{ => practice}/high-scores/high_scores.rb | 0 exercises/{ => practice}/high-scores/high_scores_test.rb | 0 exercises/{ => practice}/house/.meta/solutions/house.rb | 0 exercises/{ => practice}/house/.meta/tests.toml | 0 exercises/{ => practice}/house/README.md | 0 exercises/{ => practice}/house/house.rb | 0 exercises/{ => practice}/house/house_test.rb | 0 .../isbn-verifier/.meta/generator/isbn_verifier_case.rb | 0 .../{ => practice}/isbn-verifier/.meta/solutions/isbn_verifier.rb | 0 exercises/{ => practice}/isbn-verifier/.meta/tests.toml | 0 exercises/{ => practice}/isbn-verifier/README.md | 0 exercises/{ => practice}/isbn-verifier/isbn_verifier.rb | 0 exercises/{ => practice}/isbn-verifier/isbn_verifier_test.rb | 0 exercises/{ => practice}/isogram/.meta/generator/isogram_case.rb | 0 exercises/{ => practice}/isogram/.meta/solutions/isogram.rb | 0 exercises/{ => practice}/isogram/.meta/tests.toml | 0 exercises/{ => practice}/isogram/README.md | 0 exercises/{ => practice}/isogram/isogram.rb | 0 exercises/{ => practice}/isogram/isogram_test.rb | 0 .../kindergarten-garden/.meta/solutions/kindergarten_garden.rb | 0 exercises/{ => practice}/kindergarten-garden/.meta/tests.toml | 0 exercises/{ => practice}/kindergarten-garden/README.md | 0 .../{ => practice}/kindergarten-garden/kindergarten_garden.rb | 0 .../kindergarten-garden/kindergarten_garden_test.rb | 0 .../.meta/generator/largest_series_product_case.rb | 0 .../.meta/solutions/largest_series_product.rb | 0 exercises/{ => practice}/largest-series-product/.meta/tests.toml | 0 exercises/{ => practice}/largest-series-product/README.md | 0 .../largest-series-product/largest_series_product.rb | 0 .../largest-series-product/largest_series_product_test.rb | 0 exercises/{ => practice}/leap/.meta/generator/leap_case.rb | 0 exercises/{ => practice}/leap/.meta/generator/test_template.erb | 0 exercises/{ => practice}/leap/.meta/solutions/leap.rb | 0 exercises/{ => practice}/leap/.meta/tests.toml | 0 exercises/{ => practice}/leap/README.md | 0 exercises/{ => practice}/leap/leap.rb | 0 exercises/{ => practice}/leap/leap_test.rb | 0 .../{ => practice}/linked-list/.meta/solutions/linked_list.rb | 0 exercises/{ => practice}/linked-list/README.md | 0 exercises/{ => practice}/linked-list/linked_list.rb | 0 exercises/{ => practice}/linked-list/linked_list_test.rb | 0 exercises/{ => practice}/list-ops/.meta/solutions/list_ops.rb | 0 exercises/{ => practice}/list-ops/.meta/tests.toml | 0 exercises/{ => practice}/list-ops/README.md | 0 exercises/{ => practice}/list-ops/list_ops.rb | 0 exercises/{ => practice}/list-ops/list_ops_test.rb | 0 exercises/{ => practice}/luhn/.meta/generator/luhn_case.rb | 0 exercises/{ => practice}/luhn/.meta/solutions/luhn.rb | 0 exercises/{ => practice}/luhn/.meta/tests.toml | 0 exercises/{ => practice}/luhn/README.md | 0 exercises/{ => practice}/luhn/luhn.rb | 0 exercises/{ => practice}/luhn/luhn_test.rb | 0 .../matching-brackets/.meta/generator/matching_brackets_case.rb | 0 .../matching-brackets/.meta/solutions/matching_brackets.rb | 0 exercises/{ => practice}/matching-brackets/.meta/tests.toml | 0 exercises/{ => practice}/matching-brackets/README.md | 0 exercises/{ => practice}/matching-brackets/matching_brackets.rb | 0 .../{ => practice}/matching-brackets/matching_brackets_test.rb | 0 exercises/{ => practice}/matrix/.meta/solutions/matrix.rb | 0 exercises/{ => practice}/matrix/.meta/tests.toml | 0 exercises/{ => practice}/matrix/README.md | 0 exercises/{ => practice}/matrix/matrix.rb | 0 exercises/{ => practice}/matrix/matrix_test.rb | 0 exercises/{ => practice}/meetup/.meta/generator/meetup_case.rb | 0 exercises/{ => practice}/meetup/.meta/solutions/meetup.rb | 0 exercises/{ => practice}/meetup/.meta/tests.toml | 0 exercises/{ => practice}/meetup/README.md | 0 exercises/{ => practice}/meetup/meetup.rb | 0 exercises/{ => practice}/meetup/meetup_test.rb | 0 exercises/{ => practice}/microwave/.meta/solutions/microwave.rb | 0 exercises/{ => practice}/microwave/README.md | 0 exercises/{ => practice}/microwave/microwave.rb | 0 exercises/{ => practice}/microwave/microwave_test.rb | 0 .../{ => practice}/minesweeper/.meta/solutions/minesweeper.rb | 0 exercises/{ => practice}/minesweeper/.meta/tests.toml | 0 exercises/{ => practice}/minesweeper/README.md | 0 exercises/{ => practice}/minesweeper/minesweeper.rb | 0 exercises/{ => practice}/minesweeper/minesweeper_test.rb | 0 .../{ => practice}/nth-prime/.meta/generator/nth_prime_case.rb | 0 exercises/{ => practice}/nth-prime/.meta/solutions/nth_prime.rb | 0 exercises/{ => practice}/nth-prime/.meta/tests.toml | 0 exercises/{ => practice}/nth-prime/README.md | 0 exercises/{ => practice}/nth-prime/nth_prime.rb | 0 exercises/{ => practice}/nth-prime/nth_prime_test.rb | 0 .../nucleotide-count/.meta/solutions/nucleotide_count.rb | 0 exercises/{ => practice}/nucleotide-count/.meta/tests.toml | 0 exercises/{ => practice}/nucleotide-count/README.md | 0 exercises/{ => practice}/nucleotide-count/nucleotide_count.rb | 0 .../{ => practice}/nucleotide-count/nucleotide_count_test.rb | 0 .../ocr-numbers/.meta/generator/ocr_numbers_case.rb | 0 exercises/{ => practice}/ocr-numbers/.meta/hints.md | 0 .../{ => practice}/ocr-numbers/.meta/solutions/ocr_numbers.rb | 0 exercises/{ => practice}/ocr-numbers/.meta/tests.toml | 0 exercises/{ => practice}/ocr-numbers/README.md | 0 exercises/{ => practice}/ocr-numbers/ocr_numbers.rb | 0 exercises/{ => practice}/ocr-numbers/ocr_numbers_test.rb | 0 exercises/{ => practice}/octal/.meta/solutions/octal.rb | 0 exercises/{ => practice}/octal/README.md | 0 exercises/{ => practice}/octal/octal.rb | 0 exercises/{ => practice}/octal/octal_test.rb | 0 .../palindrome-products/.meta/solutions/palindrome_products.rb | 0 exercises/{ => practice}/palindrome-products/.meta/tests.toml | 0 exercises/{ => practice}/palindrome-products/README.md | 0 .../{ => practice}/palindrome-products/palindrome_products.rb | 0 .../palindrome-products/palindrome_products_test.rb | 0 exercises/{ => practice}/pangram/.meta/generator/pangram_case.rb | 0 exercises/{ => practice}/pangram/.meta/solutions/pangram.rb | 0 exercises/{ => practice}/pangram/.meta/tests.toml | 0 exercises/{ => practice}/pangram/README.md | 0 exercises/{ => practice}/pangram/pangram.rb | 0 exercises/{ => practice}/pangram/pangram_test.rb | 0 .../pascals-triangle/.meta/solutions/pascals_triangle.rb | 0 exercises/{ => practice}/pascals-triangle/.meta/tests.toml | 0 exercises/{ => practice}/pascals-triangle/README.md | 0 exercises/{ => practice}/pascals-triangle/pascals_triangle.rb | 0 .../{ => practice}/pascals-triangle/pascals_triangle_test.rb | 0 .../perfect-numbers/.meta/solutions/perfect_numbers.rb | 0 exercises/{ => practice}/perfect-numbers/.meta/tests.toml | 0 exercises/{ => practice}/perfect-numbers/README.md | 0 exercises/{ => practice}/perfect-numbers/perfect_numbers.rb | 0 exercises/{ => practice}/perfect-numbers/perfect_numbers_test.rb | 0 .../phone-number/.meta/generator/phone_number_case.rb | 0 .../{ => practice}/phone-number/.meta/solutions/phone_number.rb | 0 exercises/{ => practice}/phone-number/.meta/tests.toml | 0 exercises/{ => practice}/phone-number/README.md | 0 exercises/{ => practice}/phone-number/phone_number.rb | 0 exercises/{ => practice}/phone-number/phone_number_test.rb | 0 .../{ => practice}/pig-latin/.meta/generator/pig_latin_case.rb | 0 exercises/{ => practice}/pig-latin/.meta/solutions/pig_latin.rb | 0 exercises/{ => practice}/pig-latin/.meta/tests.toml | 0 exercises/{ => practice}/pig-latin/README.md | 0 exercises/{ => practice}/pig-latin/pig_latin.rb | 0 exercises/{ => practice}/pig-latin/pig_latin_test.rb | 0 .../point-mutations/.meta/solutions/point_mutations.rb | 0 exercises/{ => practice}/point-mutations/README.md | 0 exercises/{ => practice}/point-mutations/point_mutations.rb | 0 exercises/{ => practice}/point-mutations/point_mutations_test.rb | 0 exercises/{ => practice}/poker/.meta/solutions/poker.rb | 0 exercises/{ => practice}/poker/.meta/tests.toml | 0 exercises/{ => practice}/poker/README.md | 0 exercises/{ => practice}/poker/poker.rb | 0 exercises/{ => practice}/poker/poker_test.rb | 0 .../{ => practice}/prime-factors/.meta/solutions/prime_factors.rb | 0 exercises/{ => practice}/prime-factors/.meta/tests.toml | 0 exercises/{ => practice}/prime-factors/README.md | 0 exercises/{ => practice}/prime-factors/prime_factors.rb | 0 exercises/{ => practice}/prime-factors/prime_factors_test.rb | 0 .../protein-translation/.meta/solutions/protein_translation.rb | 0 exercises/{ => practice}/protein-translation/.meta/tests.toml | 0 exercises/{ => practice}/protein-translation/README.md | 0 .../{ => practice}/protein-translation/protein_translation.rb | 0 .../protein-translation/protein_translation_test.rb | 0 exercises/{ => practice}/proverb/.meta/solutions/proverb.rb | 0 exercises/{ => practice}/proverb/.meta/tests.toml | 0 exercises/{ => practice}/proverb/README.md | 0 exercises/{ => practice}/proverb/proverb.rb | 0 exercises/{ => practice}/proverb/proverb_test.rb | 0 .../pythagorean-triplet/.meta/solutions/pythagorean_triplet.rb | 0 exercises/{ => practice}/pythagorean-triplet/.meta/tests.toml | 0 exercises/{ => practice}/pythagorean-triplet/README.md | 0 .../{ => practice}/pythagorean-triplet/pythagorean_triplet.rb | 0 .../pythagorean-triplet/pythagorean_triplet_test.rb | 0 .../queen-attack/.meta/generator/queen_attack_case.rb | 0 .../{ => practice}/queen-attack/.meta/solutions/queen_attack.rb | 0 exercises/{ => practice}/queen-attack/.meta/tests.toml | 0 exercises/{ => practice}/queen-attack/README.md | 0 exercises/{ => practice}/queen-attack/queen_attack.rb | 0 exercises/{ => practice}/queen-attack/queen_attack_test.rb | 0 .../rail-fence-cipher/.meta/solutions/rail_fence_cipher.rb | 0 exercises/{ => practice}/rail-fence-cipher/.meta/tests.toml | 0 exercises/{ => practice}/rail-fence-cipher/README.md | 0 exercises/{ => practice}/rail-fence-cipher/rail_fence_cipher.rb | 0 .../{ => practice}/rail-fence-cipher/rail_fence_cipher_test.rb | 0 .../{ => practice}/raindrops/.meta/generator/raindrops_case.rb | 0 exercises/{ => practice}/raindrops/.meta/solutions/raindrops.rb | 0 exercises/{ => practice}/raindrops/.meta/tests.toml | 0 exercises/{ => practice}/raindrops/README.md | 0 exercises/{ => practice}/raindrops/raindrops.rb | 0 exercises/{ => practice}/raindrops/raindrops_test.rb | 0 .../resistor-color-duo/.meta/generator/resistor_color_duo_case.rb | 0 .../resistor-color-duo/.meta/solutions/resistor_color_duo.rb | 0 exercises/{ => practice}/resistor-color-duo/.meta/tests.toml | 0 exercises/{ => practice}/resistor-color-duo/README.md | 0 exercises/{ => practice}/resistor-color-duo/resistor_color_duo.rb | 0 .../{ => practice}/resistor-color-duo/resistor_color_duo_test.rb | 0 .../.meta/generator/resistor_color_trio_case.rb | 0 .../resistor-color-trio/.meta/solutions/resistor_color_trio.rb | 0 exercises/{ => practice}/resistor-color-trio/.meta/tests.toml | 0 exercises/{ => practice}/resistor-color-trio/README.md | 0 .../{ => practice}/resistor-color-trio/resistor_color_trio.rb | 0 .../resistor-color-trio/resistor_color_trio_test.rb | 0 .../resistor-color/.meta/generator/resistor_color_case.rb | 0 .../resistor-color/.meta/solutions/resistor_color.rb | 0 exercises/{ => practice}/resistor-color/.meta/tests.toml | 0 exercises/{ => practice}/resistor-color/README.md | 0 exercises/{ => practice}/resistor-color/resistor_color.rb | 0 exercises/{ => practice}/resistor-color/resistor_color_test.rb | 0 .../rna-transcription/.meta/generator/rna_transcription_case.rb | 0 .../rna-transcription/.meta/solutions/rna_transcription.rb | 0 exercises/{ => practice}/rna-transcription/.meta/tests.toml | 0 exercises/{ => practice}/rna-transcription/README.md | 0 exercises/{ => practice}/rna-transcription/rna_transcription.rb | 0 .../{ => practice}/rna-transcription/rna_transcription_test.rb | 0 exercises/{ => practice}/robot-name/.meta/hints.md | 0 exercises/{ => practice}/robot-name/.meta/solutions/robot_name.rb | 0 exercises/{ => practice}/robot-name/README.md | 0 exercises/{ => practice}/robot-name/robot_name.rb | 0 exercises/{ => practice}/robot-name/robot_name_test.rb | 0 .../robot-simulator/.meta/solutions/robot_simulator.rb | 0 exercises/{ => practice}/robot-simulator/.meta/tests.toml | 0 exercises/{ => practice}/robot-simulator/README.md | 0 exercises/{ => practice}/robot-simulator/robot_simulator.rb | 0 exercises/{ => practice}/robot-simulator/robot_simulator_test.rb | 0 .../roman-numerals/.meta/generator/roman_numerals_case.rb | 0 .../roman-numerals/.meta/solutions/roman_numerals.rb | 0 exercises/{ => practice}/roman-numerals/.meta/tests.toml | 0 exercises/{ => practice}/roman-numerals/README.md | 0 exercises/{ => practice}/roman-numerals/roman_numerals.rb | 0 exercises/{ => practice}/roman-numerals/roman_numerals_test.rb | 0 .../rotational-cipher/.meta/generator/rotational_cipher_case.rb | 0 .../rotational-cipher/.meta/solutions/rotational_cipher.rb | 0 exercises/{ => practice}/rotational-cipher/.meta/tests.toml | 0 exercises/{ => practice}/rotational-cipher/README.md | 0 exercises/{ => practice}/rotational-cipher/rotational_cipher.rb | 0 .../{ => practice}/rotational-cipher/rotational_cipher_test.rb | 0 .../.meta/generator/run_length_encoding_case.rb | 0 .../run-length-encoding/.meta/solutions/run_length_encoding.rb | 0 exercises/{ => practice}/run-length-encoding/.meta/tests.toml | 0 exercises/{ => practice}/run-length-encoding/README.md | 0 .../{ => practice}/run-length-encoding/run_length_encoding.rb | 0 .../run-length-encoding/run_length_encoding_test.rb | 0 .../{ => practice}/saddle-points/.meta/solutions/saddle_points.rb | 0 exercises/{ => practice}/saddle-points/.meta/tests.toml | 0 exercises/{ => practice}/saddle-points/README.md | 0 exercises/{ => practice}/saddle-points/saddle_points.rb | 0 exercises/{ => practice}/saddle-points/saddle_points_test.rb | 0 exercises/{ => practice}/say/.meta/generator/say_case.rb | 0 exercises/{ => practice}/say/.meta/solutions/say.rb | 0 exercises/{ => practice}/say/.meta/tests.toml | 0 exercises/{ => practice}/say/README.md | 0 exercises/{ => practice}/say/say.rb | 0 exercises/{ => practice}/say/say_test.rb | 0 .../scale-generator/.meta/solutions/scale_generator.rb | 0 exercises/{ => practice}/scale-generator/.meta/tests.toml | 0 exercises/{ => practice}/scale-generator/README.md | 0 exercises/{ => practice}/scale-generator/scale_generator.rb | 0 exercises/{ => practice}/scale-generator/scale_generator_test.rb | 0 .../scrabble-score/.meta/solutions/scrabble_score.rb | 0 exercises/{ => practice}/scrabble-score/.meta/tests.toml | 0 exercises/{ => practice}/scrabble-score/README.md | 0 exercises/{ => practice}/scrabble-score/scrabble_score.rb | 0 exercises/{ => practice}/scrabble-score/scrabble_score_test.rb | 0 .../secret-handshake/.meta/solutions/secret_handshake.rb | 0 exercises/{ => practice}/secret-handshake/.meta/tests.toml | 0 exercises/{ => practice}/secret-handshake/README.md | 0 exercises/{ => practice}/secret-handshake/secret_handshake.rb | 0 .../{ => practice}/secret-handshake/secret_handshake_test.rb | 0 exercises/{ => practice}/series/.meta/hints.md | 0 exercises/{ => practice}/series/.meta/solutions/series.rb | 0 exercises/{ => practice}/series/.meta/tests.toml | 0 exercises/{ => practice}/series/README.md | 0 exercises/{ => practice}/series/series.rb | 0 exercises/{ => practice}/series/series_test.rb | 0 exercises/{ => practice}/sieve/.meta/generator/sieve_case.rb | 0 exercises/{ => practice}/sieve/.meta/solutions/sieve.rb | 0 exercises/{ => practice}/sieve/.meta/tests.toml | 0 exercises/{ => practice}/sieve/README.md | 0 exercises/{ => practice}/sieve/sieve.rb | 0 exercises/{ => practice}/sieve/sieve_test.rb | 0 .../{ => practice}/simple-cipher/.meta/solutions/simple_cipher.rb | 0 exercises/{ => practice}/simple-cipher/.meta/tests.toml | 0 exercises/{ => practice}/simple-cipher/README.md | 0 exercises/{ => practice}/simple-cipher/simple_cipher.rb | 0 exercises/{ => practice}/simple-cipher/simple_cipher_test.rb | 0 .../simple-linked-list/.meta/solutions/simple_linked_list.rb | 0 exercises/{ => practice}/simple-linked-list/README.md | 0 exercises/{ => practice}/simple-linked-list/simple_linked_list.rb | 0 .../{ => practice}/simple-linked-list/simple_linked_list_test.rb | 0 .../{ => practice}/space-age/.meta/generator/space_age_case.rb | 0 .../{ => practice}/space-age/.meta/generator/test_template.erb | 0 exercises/{ => practice}/space-age/.meta/solutions/space_age.rb | 0 exercises/{ => practice}/space-age/.meta/tests.toml | 0 exercises/{ => practice}/space-age/README.md | 0 exercises/{ => practice}/space-age/space_age.rb | 0 exercises/{ => practice}/space-age/space_age_test.rb | 0 exercises/{ => practice}/strain/.meta/solutions/strain.rb | 0 exercises/{ => practice}/strain/README.md | 0 exercises/{ => practice}/strain/strain.rb | 0 exercises/{ => practice}/strain/strain_test.rb | 0 .../sum-of-multiples/.meta/generator/sum_of_multiples_case.rb | 0 .../sum-of-multiples/.meta/solutions/sum_of_multiples.rb | 0 exercises/{ => practice}/sum-of-multiples/.meta/tests.toml | 0 exercises/{ => practice}/sum-of-multiples/README.md | 0 exercises/{ => practice}/sum-of-multiples/sum_of_multiples.rb | 0 .../{ => practice}/sum-of-multiples/sum_of_multiples_test.rb | 0 .../{ => practice}/tournament/.meta/generator/tournament_case.rb | 0 exercises/{ => practice}/tournament/.meta/solutions/tournament.rb | 0 exercises/{ => practice}/tournament/.meta/tests.toml | 0 exercises/{ => practice}/tournament/README.md | 0 exercises/{ => practice}/tournament/tournament.rb | 0 exercises/{ => practice}/tournament/tournament_test.rb | 0 .../{ => practice}/transpose/.meta/generator/transpose_case.rb | 0 exercises/{ => practice}/transpose/.meta/solutions/transpose.rb | 0 exercises/{ => practice}/transpose/.meta/tests.toml | 0 exercises/{ => practice}/transpose/README.md | 0 exercises/{ => practice}/transpose/transpose.rb | 0 exercises/{ => practice}/transpose/transpose_test.rb | 0 .../{ => practice}/triangle/.meta/generator/triangle_case.rb | 0 exercises/{ => practice}/triangle/.meta/solutions/triangle.rb | 0 exercises/{ => practice}/triangle/.meta/tests.toml | 0 exercises/{ => practice}/triangle/README.md | 0 exercises/{ => practice}/triangle/triangle.rb | 0 exercises/{ => practice}/triangle/triangle_test.rb | 0 exercises/{ => practice}/trinary/.meta/solutions/trinary.rb | 0 exercises/{ => practice}/trinary/.meta/tests.toml | 0 exercises/{ => practice}/trinary/README.md | 0 exercises/{ => practice}/trinary/trinary.rb | 0 exercises/{ => practice}/trinary/trinary_test.rb | 0 .../{ => practice}/twelve-days/.meta/solutions/twelve_days.rb | 0 exercises/{ => practice}/twelve-days/.meta/tests.toml | 0 exercises/{ => practice}/twelve-days/README.md | 0 exercises/{ => practice}/twelve-days/song.txt | 0 exercises/{ => practice}/twelve-days/twelve_days.rb | 0 exercises/{ => practice}/twelve-days/twelve_days_test.rb | 0 .../{ => practice}/two-bucket/.meta/generator/two_bucket_case.rb | 0 exercises/{ => practice}/two-bucket/.meta/solutions/two_bucket.rb | 0 exercises/{ => practice}/two-bucket/.meta/tests.toml | 0 exercises/{ => practice}/two-bucket/README.md | 0 exercises/{ => practice}/two-bucket/two_bucket.rb | 0 exercises/{ => practice}/two-bucket/two_bucket_test.rb | 0 exercises/{ => practice}/two-fer/.meta/generator/two_fer_case.rb | 0 exercises/{ => practice}/two-fer/.meta/solutions/two_fer.rb | 0 exercises/{ => practice}/two-fer/.meta/tests.toml | 0 exercises/{ => practice}/two-fer/README.md | 0 exercises/{ => practice}/two-fer/two_fer.rb | 0 exercises/{ => practice}/two-fer/two_fer_test.rb | 0 .../{ => practice}/word-count/.meta/generator/word_count_case.rb | 0 exercises/{ => practice}/word-count/.meta/solutions/word_count.rb | 0 exercises/{ => practice}/word-count/.meta/tests.toml | 0 exercises/{ => practice}/word-count/README.md | 0 exercises/{ => practice}/word-count/word_count.rb | 0 exercises/{ => practice}/word-count/word_count_test.rb | 0 exercises/{ => practice}/wordy/.meta/generator/wordy_case.rb | 0 exercises/{ => practice}/wordy/.meta/solutions/wordy.rb | 0 exercises/{ => practice}/wordy/.meta/tests.toml | 0 exercises/{ => practice}/wordy/README.md | 0 exercises/{ => practice}/wordy/wordy.rb | 0 exercises/{ => practice}/wordy/wordy_test.rb | 0 exercises/{ => practice}/zipper/.meta/generator/zipper_case.rb | 0 exercises/{ => practice}/zipper/.meta/solutions/zipper.rb | 0 exercises/{ => practice}/zipper/.meta/tests.toml | 0 exercises/{ => practice}/zipper/README.md | 0 exercises/{ => practice}/zipper/zipper.rb | 0 exercises/{ => practice}/zipper/zipper_test.rb | 0 584 files changed, 0 insertions(+), 0 deletions(-) rename exercises/{ => practice}/accumulate/.meta/hints.md (100%) rename exercises/{ => practice}/accumulate/.meta/solutions/accumulate.rb (100%) rename exercises/{ => practice}/accumulate/README.md (100%) rename exercises/{ => practice}/accumulate/accumulate.rb (100%) rename exercises/{ => practice}/accumulate/accumulate_test.rb (100%) rename exercises/{ => practice}/acronym/.meta/generator/acronym_case.rb (100%) rename exercises/{ => practice}/acronym/.meta/solutions/acronym.rb (100%) rename exercises/{ => practice}/acronym/.meta/tests.toml (100%) rename exercises/{ => practice}/acronym/README.md (100%) rename exercises/{ => practice}/acronym/acronym.rb (100%) rename exercises/{ => practice}/acronym/acronym_test.rb (100%) rename exercises/{ => practice}/affine-cipher/.meta/generator/affine_cipher_case.rb (100%) rename exercises/{ => practice}/affine-cipher/.meta/solutions/affine_cipher.rb (100%) rename exercises/{ => practice}/affine-cipher/.meta/tests.toml (100%) rename exercises/{ => practice}/affine-cipher/README.md (100%) rename exercises/{ => practice}/affine-cipher/affine_cipher.rb (100%) rename exercises/{ => practice}/affine-cipher/affine_cipher_test.rb (100%) rename exercises/{ => practice}/all-your-base/.meta/generator/all_your_base_case.rb (100%) rename exercises/{ => practice}/all-your-base/.meta/solutions/all_your_base.rb (100%) rename exercises/{ => practice}/all-your-base/.meta/tests.toml (100%) rename exercises/{ => practice}/all-your-base/README.md (100%) rename exercises/{ => practice}/all-your-base/all_your_base.rb (100%) rename exercises/{ => practice}/all-your-base/all_your_base_test.rb (100%) rename exercises/{ => practice}/allergies/.meta/generator/allergies_case.rb (100%) rename exercises/{ => practice}/allergies/.meta/solutions/allergies.rb (100%) rename exercises/{ => practice}/allergies/.meta/tests.toml (100%) rename exercises/{ => practice}/allergies/README.md (100%) rename exercises/{ => practice}/allergies/allergies.rb (100%) rename exercises/{ => practice}/allergies/allergies_test.rb (100%) rename exercises/{ => practice}/alphametics/.meta/generator/alphametics_case.rb (100%) rename exercises/{ => practice}/alphametics/.meta/solutions/alphametics.rb (100%) rename exercises/{ => practice}/alphametics/.meta/solutions/alphametics_compact.rb (100%) rename exercises/{ => practice}/alphametics/.meta/tests.toml (100%) rename exercises/{ => practice}/alphametics/README.md (100%) rename exercises/{ => practice}/alphametics/alphametics.rb (100%) rename exercises/{ => practice}/alphametics/alphametics_test.rb (100%) rename exercises/{ => practice}/anagram/.meta/generator/anagram_case.rb (100%) rename exercises/{ => practice}/anagram/.meta/solutions/anagram.rb (100%) rename exercises/{ => practice}/anagram/.meta/tests.toml (100%) rename exercises/{ => practice}/anagram/README.md (100%) rename exercises/{ => practice}/anagram/anagram.rb (100%) rename exercises/{ => practice}/anagram/anagram_test.rb (100%) rename exercises/{ => practice}/armstrong-numbers/.meta/generator/armstrong_numbers_case.rb (100%) rename exercises/{ => practice}/armstrong-numbers/.meta/solutions/armstrong_numbers.rb (100%) rename exercises/{ => practice}/armstrong-numbers/.meta/tests.toml (100%) rename exercises/{ => practice}/armstrong-numbers/README.md (100%) rename exercises/{ => practice}/armstrong-numbers/armstrong_numbers.rb (100%) rename exercises/{ => practice}/armstrong-numbers/armstrong_numbers_test.rb (100%) rename exercises/{ => practice}/atbash-cipher/.meta/generator/atbash_cipher_case.rb (100%) rename exercises/{ => practice}/atbash-cipher/.meta/solutions/atbash_cipher.rb (100%) rename exercises/{ => practice}/atbash-cipher/.meta/tests.toml (100%) rename exercises/{ => practice}/atbash-cipher/README.md (100%) rename exercises/{ => practice}/atbash-cipher/atbash_cipher.rb (100%) rename exercises/{ => practice}/atbash-cipher/atbash_cipher_test.rb (100%) rename exercises/{ => practice}/beer-song/.meta/generator/beer_song_case.rb (100%) rename exercises/{ => practice}/beer-song/.meta/solutions/beer_song.rb (100%) rename exercises/{ => practice}/beer-song/.meta/tests.toml (100%) rename exercises/{ => practice}/beer-song/README.md (100%) rename exercises/{ => practice}/beer-song/beer_song.rb (100%) rename exercises/{ => practice}/beer-song/beer_song_test.rb (100%) rename exercises/{ => practice}/binary-search-tree/.meta/solutions/binary_search_tree.rb (100%) rename exercises/{ => practice}/binary-search-tree/.meta/tests.toml (100%) rename exercises/{ => practice}/binary-search-tree/README.md (100%) rename exercises/{ => practice}/binary-search-tree/binary_search_tree.rb (100%) rename exercises/{ => practice}/binary-search-tree/binary_search_tree_test.rb (100%) rename exercises/{ => practice}/binary-search/.meta/generator/binary_search_case.rb (100%) rename exercises/{ => practice}/binary-search/.meta/solutions/binary_search.rb (100%) rename exercises/{ => practice}/binary-search/.meta/tests.toml (100%) rename exercises/{ => practice}/binary-search/README.md (100%) rename exercises/{ => practice}/binary-search/binary_search.rb (100%) rename exercises/{ => practice}/binary-search/binary_search_test.rb (100%) rename exercises/{ => practice}/binary/.meta/generator/binary_case.rb (100%) rename exercises/{ => practice}/binary/.meta/solutions/binary.rb (100%) rename exercises/{ => practice}/binary/.meta/tests.toml (100%) rename exercises/{ => practice}/binary/README.md (100%) rename exercises/{ => practice}/binary/binary.rb (100%) rename exercises/{ => practice}/binary/binary_test.rb (100%) rename exercises/{ => practice}/bob/.meta/generator/bob_case.rb (100%) rename exercises/{ => practice}/bob/.meta/solutions/bob.rb (100%) rename exercises/{ => practice}/bob/.meta/tests.toml (100%) rename exercises/{ => practice}/bob/README.md (100%) rename exercises/{ => practice}/bob/bob.rb (100%) rename exercises/{ => practice}/bob/bob_test.rb (100%) rename exercises/{ => practice}/book-store/.meta/generator/book_store_case.rb (100%) rename exercises/{ => practice}/book-store/.meta/solutions/book_store.rb (100%) rename exercises/{ => practice}/book-store/.meta/tests.toml (100%) rename exercises/{ => practice}/book-store/README.md (100%) rename exercises/{ => practice}/book-store/book_store.rb (100%) rename exercises/{ => practice}/book-store/book_store_test.rb (100%) rename exercises/{ => practice}/bowling/.meta/generator/bowling_case.rb (100%) rename exercises/{ => practice}/bowling/.meta/solutions/bowling.rb (100%) rename exercises/{ => practice}/bowling/.meta/tests.toml (100%) rename exercises/{ => practice}/bowling/README.md (100%) rename exercises/{ => practice}/bowling/bowling.rb (100%) rename exercises/{ => practice}/bowling/bowling_test.rb (100%) rename exercises/{ => practice}/change/.meta/generator/change_case.rb (100%) rename exercises/{ => practice}/change/.meta/solutions/change.rb (100%) rename exercises/{ => practice}/change/.meta/tests.toml (100%) rename exercises/{ => practice}/change/README.md (100%) rename exercises/{ => practice}/change/change.rb (100%) rename exercises/{ => practice}/change/change_test.rb (100%) rename exercises/{ => practice}/circular-buffer/.meta/solutions/circular_buffer.rb (100%) rename exercises/{ => practice}/circular-buffer/.meta/tests.toml (100%) rename exercises/{ => practice}/circular-buffer/README.md (100%) rename exercises/{ => practice}/circular-buffer/circular_buffer.rb (100%) rename exercises/{ => practice}/circular-buffer/circular_buffer_test.rb (100%) rename exercises/{ => practice}/clock/.meta/generator/clock_case.rb (100%) rename exercises/{ => practice}/clock/.meta/solutions/clock.rb (100%) rename exercises/{ => practice}/clock/.meta/tests.toml (100%) rename exercises/{ => practice}/clock/README.md (100%) rename exercises/{ => practice}/clock/clock.rb (100%) rename exercises/{ => practice}/clock/clock_test.rb (100%) rename exercises/{ => practice}/collatz-conjecture/.meta/generator/collatz_conjecture_case.rb (100%) rename exercises/{ => practice}/collatz-conjecture/.meta/solutions/collatz_conjecture.rb (100%) rename exercises/{ => practice}/collatz-conjecture/.meta/tests.toml (100%) rename exercises/{ => practice}/collatz-conjecture/README.md (100%) rename exercises/{ => practice}/collatz-conjecture/collatz_conjecture.rb (100%) rename exercises/{ => practice}/collatz-conjecture/collatz_conjecture_test.rb (100%) rename exercises/{ => practice}/complex-numbers/.meta/generator/complex_numbers_case.rb (100%) rename exercises/{ => practice}/complex-numbers/.meta/solutions/complex_numbers.rb (100%) rename exercises/{ => practice}/complex-numbers/.meta/tests.toml (100%) rename exercises/{ => practice}/complex-numbers/README.md (100%) rename exercises/{ => practice}/complex-numbers/complex_numbers.rb (100%) rename exercises/{ => practice}/complex-numbers/complex_numbers_test.rb (100%) rename exercises/{ => practice}/connect/.meta/generator/connect_case.rb (100%) rename exercises/{ => practice}/connect/.meta/solutions/connect.rb (100%) rename exercises/{ => practice}/connect/.meta/tests.toml (100%) rename exercises/{ => practice}/connect/README.md (100%) rename exercises/{ => practice}/connect/connect.rb (100%) rename exercises/{ => practice}/connect/connect_test.rb (100%) rename exercises/{ => practice}/crypto-square/.meta/generator/crypto_square_case.rb (100%) rename exercises/{ => practice}/crypto-square/.meta/solutions/crypto_square.rb (100%) rename exercises/{ => practice}/crypto-square/.meta/tests.toml (100%) rename exercises/{ => practice}/crypto-square/README.md (100%) rename exercises/{ => practice}/crypto-square/crypto_square.rb (100%) rename exercises/{ => practice}/crypto-square/crypto_square_test.rb (100%) rename exercises/{ => practice}/custom-set/.meta/generator/custom_set_case.rb (100%) rename exercises/{ => practice}/custom-set/.meta/solutions/custom_set.rb (100%) rename exercises/{ => practice}/custom-set/.meta/tests.toml (100%) rename exercises/{ => practice}/custom-set/README.md (100%) rename exercises/{ => practice}/custom-set/custom_set.rb (100%) rename exercises/{ => practice}/custom-set/custom_set_test.rb (100%) rename exercises/{ => practice}/darts/.meta/generator/darts_case.rb (100%) rename exercises/{ => practice}/darts/.meta/solutions/darts.rb (100%) rename exercises/{ => practice}/darts/.meta/tests.toml (100%) rename exercises/{ => practice}/darts/README.md (100%) rename exercises/{ => practice}/darts/darts.rb (100%) rename exercises/{ => practice}/darts/darts_test.rb (100%) rename exercises/{ => practice}/diamond/.meta/solutions/diamond.rb (100%) rename exercises/{ => practice}/diamond/.meta/tests.toml (100%) rename exercises/{ => practice}/diamond/README.md (100%) rename exercises/{ => practice}/diamond/diamond.rb (100%) rename exercises/{ => practice}/diamond/diamond_test.rb (100%) rename exercises/{ => practice}/difference-of-squares/.meta/generator/difference_of_squares_case.rb (100%) rename exercises/{ => practice}/difference-of-squares/.meta/solutions/difference_of_squares.rb (100%) rename exercises/{ => practice}/difference-of-squares/.meta/tests.toml (100%) rename exercises/{ => practice}/difference-of-squares/README.md (100%) rename exercises/{ => practice}/difference-of-squares/difference_of_squares.rb (100%) rename exercises/{ => practice}/difference-of-squares/difference_of_squares_test.rb (100%) rename exercises/{ => practice}/dominoes/.meta/generator/dominoes_case.rb (100%) rename exercises/{ => practice}/dominoes/.meta/solutions/dominoes.rb (100%) rename exercises/{ => practice}/dominoes/.meta/tests.toml (100%) rename exercises/{ => practice}/dominoes/README.md (100%) rename exercises/{ => practice}/dominoes/dominoes.rb (100%) rename exercises/{ => practice}/dominoes/dominoes_test.rb (100%) rename exercises/{ => practice}/etl/.meta/generator/etl_case.rb (100%) rename exercises/{ => practice}/etl/.meta/solutions/etl.rb (100%) rename exercises/{ => practice}/etl/.meta/tests.toml (100%) rename exercises/{ => practice}/etl/README.md (100%) rename exercises/{ => practice}/etl/etl.rb (100%) rename exercises/{ => practice}/etl/etl_test.rb (100%) rename exercises/{ => practice}/flatten-array/.meta/generator/flatten_array_case.rb (100%) rename exercises/{ => practice}/flatten-array/.meta/solutions/flatten_array.rb (100%) rename exercises/{ => practice}/flatten-array/.meta/tests.toml (100%) rename exercises/{ => practice}/flatten-array/README.md (100%) rename exercises/{ => practice}/flatten-array/flatten_array.rb (100%) rename exercises/{ => practice}/flatten-array/flatten_array_test.rb (100%) rename exercises/{ => practice}/food-chain/.meta/solutions/food_chain.rb (100%) rename exercises/{ => practice}/food-chain/.meta/tests.toml (100%) rename exercises/{ => practice}/food-chain/README.md (100%) rename exercises/{ => practice}/food-chain/food_chain.rb (100%) rename exercises/{ => practice}/food-chain/food_chain_test.rb (100%) rename exercises/{ => practice}/food-chain/song.txt (100%) rename exercises/{ => practice}/gigasecond/.meta/generator/gigasecond_case.rb (100%) rename exercises/{ => practice}/gigasecond/.meta/solutions/gigasecond.rb (100%) rename exercises/{ => practice}/gigasecond/.meta/tests.toml (100%) rename exercises/{ => practice}/gigasecond/README.md (100%) rename exercises/{ => practice}/gigasecond/gigasecond.rb (100%) rename exercises/{ => practice}/gigasecond/gigasecond_test.rb (100%) rename exercises/{ => practice}/grade-school/.meta/solutions/grade_school.rb (100%) rename exercises/{ => practice}/grade-school/.meta/tests.toml (100%) rename exercises/{ => practice}/grade-school/README.md (100%) rename exercises/{ => practice}/grade-school/grade_school.rb (100%) rename exercises/{ => practice}/grade-school/grade_school_test.rb (100%) rename exercises/{ => practice}/grains/.meta/generator/grains_case.rb (100%) rename exercises/{ => practice}/grains/.meta/solutions/grains.rb (100%) rename exercises/{ => practice}/grains/README.md (100%) rename exercises/{ => practice}/grains/grains.rb (100%) rename exercises/{ => practice}/grains/grains_test.rb (100%) rename exercises/{ => practice}/grep/.meta/generator/grep_case.rb (100%) rename exercises/{ => practice}/grep/.meta/generator/test_template.erb (100%) rename exercises/{ => practice}/grep/.meta/solutions/grep.rb (100%) rename exercises/{ => practice}/grep/.meta/tests.toml (100%) rename exercises/{ => practice}/grep/README.md (100%) rename exercises/{ => practice}/grep/grep.rb (100%) rename exercises/{ => practice}/grep/grep_test.rb (100%) rename exercises/{ => practice}/hamming/.meta/generator/hamming_case.rb (100%) rename exercises/{ => practice}/hamming/.meta/solutions/hamming.rb (100%) rename exercises/{ => practice}/hamming/.meta/tests.toml (100%) rename exercises/{ => practice}/hamming/README.md (100%) rename exercises/{ => practice}/hamming/RUNNING_TESTS.md (100%) rename exercises/{ => practice}/hamming/hamming.rb (100%) rename exercises/{ => practice}/hamming/hamming_test.rb (100%) rename exercises/{ => practice}/hello-world/.meta/generator/hello_world_case.rb (100%) rename exercises/{ => practice}/hello-world/.meta/generator/test_template.erb (100%) rename exercises/{ => practice}/hello-world/.meta/solutions/hello_world.rb (100%) rename exercises/{ => practice}/hello-world/.meta/tests.toml (100%) rename exercises/{ => practice}/hello-world/GETTING_STARTED.md (100%) rename exercises/{ => practice}/hello-world/README.md (100%) rename exercises/{ => practice}/hello-world/hello_world.rb (100%) rename exercises/{ => practice}/hello-world/hello_world_test.rb (100%) rename exercises/{ => practice}/hexadecimal/.meta/solutions/hexadecimal.rb (100%) rename exercises/{ => practice}/hexadecimal/README.md (100%) rename exercises/{ => practice}/hexadecimal/hexadecimal.rb (100%) rename exercises/{ => practice}/hexadecimal/hexadecimal_test.rb (100%) rename exercises/{ => practice}/high-scores/.meta/generator/high_scores_case.rb (100%) rename exercises/{ => practice}/high-scores/.meta/hints.md (100%) rename exercises/{ => practice}/high-scores/.meta/solutions/high_scores.rb (100%) rename exercises/{ => practice}/high-scores/.meta/tests.toml (100%) rename exercises/{ => practice}/high-scores/README.md (100%) rename exercises/{ => practice}/high-scores/high_scores.rb (100%) rename exercises/{ => practice}/high-scores/high_scores_test.rb (100%) rename exercises/{ => practice}/house/.meta/solutions/house.rb (100%) rename exercises/{ => practice}/house/.meta/tests.toml (100%) rename exercises/{ => practice}/house/README.md (100%) rename exercises/{ => practice}/house/house.rb (100%) rename exercises/{ => practice}/house/house_test.rb (100%) rename exercises/{ => practice}/isbn-verifier/.meta/generator/isbn_verifier_case.rb (100%) rename exercises/{ => practice}/isbn-verifier/.meta/solutions/isbn_verifier.rb (100%) rename exercises/{ => practice}/isbn-verifier/.meta/tests.toml (100%) rename exercises/{ => practice}/isbn-verifier/README.md (100%) rename exercises/{ => practice}/isbn-verifier/isbn_verifier.rb (100%) rename exercises/{ => practice}/isbn-verifier/isbn_verifier_test.rb (100%) rename exercises/{ => practice}/isogram/.meta/generator/isogram_case.rb (100%) rename exercises/{ => practice}/isogram/.meta/solutions/isogram.rb (100%) rename exercises/{ => practice}/isogram/.meta/tests.toml (100%) rename exercises/{ => practice}/isogram/README.md (100%) rename exercises/{ => practice}/isogram/isogram.rb (100%) rename exercises/{ => practice}/isogram/isogram_test.rb (100%) rename exercises/{ => practice}/kindergarten-garden/.meta/solutions/kindergarten_garden.rb (100%) rename exercises/{ => practice}/kindergarten-garden/.meta/tests.toml (100%) rename exercises/{ => practice}/kindergarten-garden/README.md (100%) rename exercises/{ => practice}/kindergarten-garden/kindergarten_garden.rb (100%) rename exercises/{ => practice}/kindergarten-garden/kindergarten_garden_test.rb (100%) rename exercises/{ => practice}/largest-series-product/.meta/generator/largest_series_product_case.rb (100%) rename exercises/{ => practice}/largest-series-product/.meta/solutions/largest_series_product.rb (100%) rename exercises/{ => practice}/largest-series-product/.meta/tests.toml (100%) rename exercises/{ => practice}/largest-series-product/README.md (100%) rename exercises/{ => practice}/largest-series-product/largest_series_product.rb (100%) rename exercises/{ => practice}/largest-series-product/largest_series_product_test.rb (100%) rename exercises/{ => practice}/leap/.meta/generator/leap_case.rb (100%) rename exercises/{ => practice}/leap/.meta/generator/test_template.erb (100%) rename exercises/{ => practice}/leap/.meta/solutions/leap.rb (100%) rename exercises/{ => practice}/leap/.meta/tests.toml (100%) rename exercises/{ => practice}/leap/README.md (100%) rename exercises/{ => practice}/leap/leap.rb (100%) rename exercises/{ => practice}/leap/leap_test.rb (100%) rename exercises/{ => practice}/linked-list/.meta/solutions/linked_list.rb (100%) rename exercises/{ => practice}/linked-list/README.md (100%) rename exercises/{ => practice}/linked-list/linked_list.rb (100%) rename exercises/{ => practice}/linked-list/linked_list_test.rb (100%) rename exercises/{ => practice}/list-ops/.meta/solutions/list_ops.rb (100%) rename exercises/{ => practice}/list-ops/.meta/tests.toml (100%) rename exercises/{ => practice}/list-ops/README.md (100%) rename exercises/{ => practice}/list-ops/list_ops.rb (100%) rename exercises/{ => practice}/list-ops/list_ops_test.rb (100%) rename exercises/{ => practice}/luhn/.meta/generator/luhn_case.rb (100%) rename exercises/{ => practice}/luhn/.meta/solutions/luhn.rb (100%) rename exercises/{ => practice}/luhn/.meta/tests.toml (100%) rename exercises/{ => practice}/luhn/README.md (100%) rename exercises/{ => practice}/luhn/luhn.rb (100%) rename exercises/{ => practice}/luhn/luhn_test.rb (100%) rename exercises/{ => practice}/matching-brackets/.meta/generator/matching_brackets_case.rb (100%) rename exercises/{ => practice}/matching-brackets/.meta/solutions/matching_brackets.rb (100%) rename exercises/{ => practice}/matching-brackets/.meta/tests.toml (100%) rename exercises/{ => practice}/matching-brackets/README.md (100%) rename exercises/{ => practice}/matching-brackets/matching_brackets.rb (100%) rename exercises/{ => practice}/matching-brackets/matching_brackets_test.rb (100%) rename exercises/{ => practice}/matrix/.meta/solutions/matrix.rb (100%) rename exercises/{ => practice}/matrix/.meta/tests.toml (100%) rename exercises/{ => practice}/matrix/README.md (100%) rename exercises/{ => practice}/matrix/matrix.rb (100%) rename exercises/{ => practice}/matrix/matrix_test.rb (100%) rename exercises/{ => practice}/meetup/.meta/generator/meetup_case.rb (100%) rename exercises/{ => practice}/meetup/.meta/solutions/meetup.rb (100%) rename exercises/{ => practice}/meetup/.meta/tests.toml (100%) rename exercises/{ => practice}/meetup/README.md (100%) rename exercises/{ => practice}/meetup/meetup.rb (100%) rename exercises/{ => practice}/meetup/meetup_test.rb (100%) rename exercises/{ => practice}/microwave/.meta/solutions/microwave.rb (100%) rename exercises/{ => practice}/microwave/README.md (100%) rename exercises/{ => practice}/microwave/microwave.rb (100%) rename exercises/{ => practice}/microwave/microwave_test.rb (100%) rename exercises/{ => practice}/minesweeper/.meta/solutions/minesweeper.rb (100%) rename exercises/{ => practice}/minesweeper/.meta/tests.toml (100%) rename exercises/{ => practice}/minesweeper/README.md (100%) rename exercises/{ => practice}/minesweeper/minesweeper.rb (100%) rename exercises/{ => practice}/minesweeper/minesweeper_test.rb (100%) rename exercises/{ => practice}/nth-prime/.meta/generator/nth_prime_case.rb (100%) rename exercises/{ => practice}/nth-prime/.meta/solutions/nth_prime.rb (100%) rename exercises/{ => practice}/nth-prime/.meta/tests.toml (100%) rename exercises/{ => practice}/nth-prime/README.md (100%) rename exercises/{ => practice}/nth-prime/nth_prime.rb (100%) rename exercises/{ => practice}/nth-prime/nth_prime_test.rb (100%) rename exercises/{ => practice}/nucleotide-count/.meta/solutions/nucleotide_count.rb (100%) rename exercises/{ => practice}/nucleotide-count/.meta/tests.toml (100%) rename exercises/{ => practice}/nucleotide-count/README.md (100%) rename exercises/{ => practice}/nucleotide-count/nucleotide_count.rb (100%) rename exercises/{ => practice}/nucleotide-count/nucleotide_count_test.rb (100%) rename exercises/{ => practice}/ocr-numbers/.meta/generator/ocr_numbers_case.rb (100%) rename exercises/{ => practice}/ocr-numbers/.meta/hints.md (100%) rename exercises/{ => practice}/ocr-numbers/.meta/solutions/ocr_numbers.rb (100%) rename exercises/{ => practice}/ocr-numbers/.meta/tests.toml (100%) rename exercises/{ => practice}/ocr-numbers/README.md (100%) rename exercises/{ => practice}/ocr-numbers/ocr_numbers.rb (100%) rename exercises/{ => practice}/ocr-numbers/ocr_numbers_test.rb (100%) rename exercises/{ => practice}/octal/.meta/solutions/octal.rb (100%) rename exercises/{ => practice}/octal/README.md (100%) rename exercises/{ => practice}/octal/octal.rb (100%) rename exercises/{ => practice}/octal/octal_test.rb (100%) rename exercises/{ => practice}/palindrome-products/.meta/solutions/palindrome_products.rb (100%) rename exercises/{ => practice}/palindrome-products/.meta/tests.toml (100%) rename exercises/{ => practice}/palindrome-products/README.md (100%) rename exercises/{ => practice}/palindrome-products/palindrome_products.rb (100%) rename exercises/{ => practice}/palindrome-products/palindrome_products_test.rb (100%) rename exercises/{ => practice}/pangram/.meta/generator/pangram_case.rb (100%) rename exercises/{ => practice}/pangram/.meta/solutions/pangram.rb (100%) rename exercises/{ => practice}/pangram/.meta/tests.toml (100%) rename exercises/{ => practice}/pangram/README.md (100%) rename exercises/{ => practice}/pangram/pangram.rb (100%) rename exercises/{ => practice}/pangram/pangram_test.rb (100%) rename exercises/{ => practice}/pascals-triangle/.meta/solutions/pascals_triangle.rb (100%) rename exercises/{ => practice}/pascals-triangle/.meta/tests.toml (100%) rename exercises/{ => practice}/pascals-triangle/README.md (100%) rename exercises/{ => practice}/pascals-triangle/pascals_triangle.rb (100%) rename exercises/{ => practice}/pascals-triangle/pascals_triangle_test.rb (100%) rename exercises/{ => practice}/perfect-numbers/.meta/solutions/perfect_numbers.rb (100%) mode change 100755 => 100644 rename exercises/{ => practice}/perfect-numbers/.meta/tests.toml (100%) rename exercises/{ => practice}/perfect-numbers/README.md (100%) rename exercises/{ => practice}/perfect-numbers/perfect_numbers.rb (100%) rename exercises/{ => practice}/perfect-numbers/perfect_numbers_test.rb (100%) rename exercises/{ => practice}/phone-number/.meta/generator/phone_number_case.rb (100%) rename exercises/{ => practice}/phone-number/.meta/solutions/phone_number.rb (100%) rename exercises/{ => practice}/phone-number/.meta/tests.toml (100%) rename exercises/{ => practice}/phone-number/README.md (100%) rename exercises/{ => practice}/phone-number/phone_number.rb (100%) rename exercises/{ => practice}/phone-number/phone_number_test.rb (100%) rename exercises/{ => practice}/pig-latin/.meta/generator/pig_latin_case.rb (100%) rename exercises/{ => practice}/pig-latin/.meta/solutions/pig_latin.rb (100%) rename exercises/{ => practice}/pig-latin/.meta/tests.toml (100%) rename exercises/{ => practice}/pig-latin/README.md (100%) rename exercises/{ => practice}/pig-latin/pig_latin.rb (100%) rename exercises/{ => practice}/pig-latin/pig_latin_test.rb (100%) rename exercises/{ => practice}/point-mutations/.meta/solutions/point_mutations.rb (100%) rename exercises/{ => practice}/point-mutations/README.md (100%) rename exercises/{ => practice}/point-mutations/point_mutations.rb (100%) rename exercises/{ => practice}/point-mutations/point_mutations_test.rb (100%) rename exercises/{ => practice}/poker/.meta/solutions/poker.rb (100%) rename exercises/{ => practice}/poker/.meta/tests.toml (100%) rename exercises/{ => practice}/poker/README.md (100%) rename exercises/{ => practice}/poker/poker.rb (100%) rename exercises/{ => practice}/poker/poker_test.rb (100%) rename exercises/{ => practice}/prime-factors/.meta/solutions/prime_factors.rb (100%) rename exercises/{ => practice}/prime-factors/.meta/tests.toml (100%) rename exercises/{ => practice}/prime-factors/README.md (100%) rename exercises/{ => practice}/prime-factors/prime_factors.rb (100%) rename exercises/{ => practice}/prime-factors/prime_factors_test.rb (100%) rename exercises/{ => practice}/protein-translation/.meta/solutions/protein_translation.rb (100%) rename exercises/{ => practice}/protein-translation/.meta/tests.toml (100%) rename exercises/{ => practice}/protein-translation/README.md (100%) rename exercises/{ => practice}/protein-translation/protein_translation.rb (100%) rename exercises/{ => practice}/protein-translation/protein_translation_test.rb (100%) rename exercises/{ => practice}/proverb/.meta/solutions/proverb.rb (100%) rename exercises/{ => practice}/proverb/.meta/tests.toml (100%) rename exercises/{ => practice}/proverb/README.md (100%) rename exercises/{ => practice}/proverb/proverb.rb (100%) rename exercises/{ => practice}/proverb/proverb_test.rb (100%) rename exercises/{ => practice}/pythagorean-triplet/.meta/solutions/pythagorean_triplet.rb (100%) rename exercises/{ => practice}/pythagorean-triplet/.meta/tests.toml (100%) rename exercises/{ => practice}/pythagorean-triplet/README.md (100%) rename exercises/{ => practice}/pythagorean-triplet/pythagorean_triplet.rb (100%) rename exercises/{ => practice}/pythagorean-triplet/pythagorean_triplet_test.rb (100%) rename exercises/{ => practice}/queen-attack/.meta/generator/queen_attack_case.rb (100%) rename exercises/{ => practice}/queen-attack/.meta/solutions/queen_attack.rb (100%) rename exercises/{ => practice}/queen-attack/.meta/tests.toml (100%) rename exercises/{ => practice}/queen-attack/README.md (100%) rename exercises/{ => practice}/queen-attack/queen_attack.rb (100%) rename exercises/{ => practice}/queen-attack/queen_attack_test.rb (100%) rename exercises/{ => practice}/rail-fence-cipher/.meta/solutions/rail_fence_cipher.rb (100%) rename exercises/{ => practice}/rail-fence-cipher/.meta/tests.toml (100%) rename exercises/{ => practice}/rail-fence-cipher/README.md (100%) rename exercises/{ => practice}/rail-fence-cipher/rail_fence_cipher.rb (100%) rename exercises/{ => practice}/rail-fence-cipher/rail_fence_cipher_test.rb (100%) rename exercises/{ => practice}/raindrops/.meta/generator/raindrops_case.rb (100%) rename exercises/{ => practice}/raindrops/.meta/solutions/raindrops.rb (100%) rename exercises/{ => practice}/raindrops/.meta/tests.toml (100%) rename exercises/{ => practice}/raindrops/README.md (100%) rename exercises/{ => practice}/raindrops/raindrops.rb (100%) rename exercises/{ => practice}/raindrops/raindrops_test.rb (100%) rename exercises/{ => practice}/resistor-color-duo/.meta/generator/resistor_color_duo_case.rb (100%) rename exercises/{ => practice}/resistor-color-duo/.meta/solutions/resistor_color_duo.rb (100%) rename exercises/{ => practice}/resistor-color-duo/.meta/tests.toml (100%) rename exercises/{ => practice}/resistor-color-duo/README.md (100%) rename exercises/{ => practice}/resistor-color-duo/resistor_color_duo.rb (100%) rename exercises/{ => practice}/resistor-color-duo/resistor_color_duo_test.rb (100%) rename exercises/{ => practice}/resistor-color-trio/.meta/generator/resistor_color_trio_case.rb (100%) rename exercises/{ => practice}/resistor-color-trio/.meta/solutions/resistor_color_trio.rb (100%) rename exercises/{ => practice}/resistor-color-trio/.meta/tests.toml (100%) rename exercises/{ => practice}/resistor-color-trio/README.md (100%) rename exercises/{ => practice}/resistor-color-trio/resistor_color_trio.rb (100%) rename exercises/{ => practice}/resistor-color-trio/resistor_color_trio_test.rb (100%) rename exercises/{ => practice}/resistor-color/.meta/generator/resistor_color_case.rb (100%) rename exercises/{ => practice}/resistor-color/.meta/solutions/resistor_color.rb (100%) rename exercises/{ => practice}/resistor-color/.meta/tests.toml (100%) rename exercises/{ => practice}/resistor-color/README.md (100%) rename exercises/{ => practice}/resistor-color/resistor_color.rb (100%) rename exercises/{ => practice}/resistor-color/resistor_color_test.rb (100%) rename exercises/{ => practice}/rna-transcription/.meta/generator/rna_transcription_case.rb (100%) rename exercises/{ => practice}/rna-transcription/.meta/solutions/rna_transcription.rb (100%) rename exercises/{ => practice}/rna-transcription/.meta/tests.toml (100%) rename exercises/{ => practice}/rna-transcription/README.md (100%) rename exercises/{ => practice}/rna-transcription/rna_transcription.rb (100%) rename exercises/{ => practice}/rna-transcription/rna_transcription_test.rb (100%) rename exercises/{ => practice}/robot-name/.meta/hints.md (100%) rename exercises/{ => practice}/robot-name/.meta/solutions/robot_name.rb (100%) rename exercises/{ => practice}/robot-name/README.md (100%) rename exercises/{ => practice}/robot-name/robot_name.rb (100%) rename exercises/{ => practice}/robot-name/robot_name_test.rb (100%) rename exercises/{ => practice}/robot-simulator/.meta/solutions/robot_simulator.rb (100%) rename exercises/{ => practice}/robot-simulator/.meta/tests.toml (100%) rename exercises/{ => practice}/robot-simulator/README.md (100%) rename exercises/{ => practice}/robot-simulator/robot_simulator.rb (100%) rename exercises/{ => practice}/robot-simulator/robot_simulator_test.rb (100%) rename exercises/{ => practice}/roman-numerals/.meta/generator/roman_numerals_case.rb (100%) rename exercises/{ => practice}/roman-numerals/.meta/solutions/roman_numerals.rb (100%) rename exercises/{ => practice}/roman-numerals/.meta/tests.toml (100%) rename exercises/{ => practice}/roman-numerals/README.md (100%) rename exercises/{ => practice}/roman-numerals/roman_numerals.rb (100%) rename exercises/{ => practice}/roman-numerals/roman_numerals_test.rb (100%) rename exercises/{ => practice}/rotational-cipher/.meta/generator/rotational_cipher_case.rb (100%) rename exercises/{ => practice}/rotational-cipher/.meta/solutions/rotational_cipher.rb (100%) rename exercises/{ => practice}/rotational-cipher/.meta/tests.toml (100%) rename exercises/{ => practice}/rotational-cipher/README.md (100%) rename exercises/{ => practice}/rotational-cipher/rotational_cipher.rb (100%) rename exercises/{ => practice}/rotational-cipher/rotational_cipher_test.rb (100%) rename exercises/{ => practice}/run-length-encoding/.meta/generator/run_length_encoding_case.rb (100%) rename exercises/{ => practice}/run-length-encoding/.meta/solutions/run_length_encoding.rb (100%) rename exercises/{ => practice}/run-length-encoding/.meta/tests.toml (100%) rename exercises/{ => practice}/run-length-encoding/README.md (100%) rename exercises/{ => practice}/run-length-encoding/run_length_encoding.rb (100%) rename exercises/{ => practice}/run-length-encoding/run_length_encoding_test.rb (100%) rename exercises/{ => practice}/saddle-points/.meta/solutions/saddle_points.rb (100%) rename exercises/{ => practice}/saddle-points/.meta/tests.toml (100%) rename exercises/{ => practice}/saddle-points/README.md (100%) rename exercises/{ => practice}/saddle-points/saddle_points.rb (100%) rename exercises/{ => practice}/saddle-points/saddle_points_test.rb (100%) rename exercises/{ => practice}/say/.meta/generator/say_case.rb (100%) rename exercises/{ => practice}/say/.meta/solutions/say.rb (100%) rename exercises/{ => practice}/say/.meta/tests.toml (100%) rename exercises/{ => practice}/say/README.md (100%) rename exercises/{ => practice}/say/say.rb (100%) rename exercises/{ => practice}/say/say_test.rb (100%) rename exercises/{ => practice}/scale-generator/.meta/solutions/scale_generator.rb (100%) rename exercises/{ => practice}/scale-generator/.meta/tests.toml (100%) rename exercises/{ => practice}/scale-generator/README.md (100%) rename exercises/{ => practice}/scale-generator/scale_generator.rb (100%) rename exercises/{ => practice}/scale-generator/scale_generator_test.rb (100%) rename exercises/{ => practice}/scrabble-score/.meta/solutions/scrabble_score.rb (100%) rename exercises/{ => practice}/scrabble-score/.meta/tests.toml (100%) rename exercises/{ => practice}/scrabble-score/README.md (100%) rename exercises/{ => practice}/scrabble-score/scrabble_score.rb (100%) rename exercises/{ => practice}/scrabble-score/scrabble_score_test.rb (100%) rename exercises/{ => practice}/secret-handshake/.meta/solutions/secret_handshake.rb (100%) rename exercises/{ => practice}/secret-handshake/.meta/tests.toml (100%) rename exercises/{ => practice}/secret-handshake/README.md (100%) rename exercises/{ => practice}/secret-handshake/secret_handshake.rb (100%) rename exercises/{ => practice}/secret-handshake/secret_handshake_test.rb (100%) rename exercises/{ => practice}/series/.meta/hints.md (100%) rename exercises/{ => practice}/series/.meta/solutions/series.rb (100%) rename exercises/{ => practice}/series/.meta/tests.toml (100%) rename exercises/{ => practice}/series/README.md (100%) rename exercises/{ => practice}/series/series.rb (100%) rename exercises/{ => practice}/series/series_test.rb (100%) rename exercises/{ => practice}/sieve/.meta/generator/sieve_case.rb (100%) rename exercises/{ => practice}/sieve/.meta/solutions/sieve.rb (100%) rename exercises/{ => practice}/sieve/.meta/tests.toml (100%) rename exercises/{ => practice}/sieve/README.md (100%) rename exercises/{ => practice}/sieve/sieve.rb (100%) rename exercises/{ => practice}/sieve/sieve_test.rb (100%) rename exercises/{ => practice}/simple-cipher/.meta/solutions/simple_cipher.rb (100%) rename exercises/{ => practice}/simple-cipher/.meta/tests.toml (100%) rename exercises/{ => practice}/simple-cipher/README.md (100%) rename exercises/{ => practice}/simple-cipher/simple_cipher.rb (100%) rename exercises/{ => practice}/simple-cipher/simple_cipher_test.rb (100%) rename exercises/{ => practice}/simple-linked-list/.meta/solutions/simple_linked_list.rb (100%) rename exercises/{ => practice}/simple-linked-list/README.md (100%) rename exercises/{ => practice}/simple-linked-list/simple_linked_list.rb (100%) rename exercises/{ => practice}/simple-linked-list/simple_linked_list_test.rb (100%) rename exercises/{ => practice}/space-age/.meta/generator/space_age_case.rb (100%) rename exercises/{ => practice}/space-age/.meta/generator/test_template.erb (100%) rename exercises/{ => practice}/space-age/.meta/solutions/space_age.rb (100%) rename exercises/{ => practice}/space-age/.meta/tests.toml (100%) rename exercises/{ => practice}/space-age/README.md (100%) rename exercises/{ => practice}/space-age/space_age.rb (100%) rename exercises/{ => practice}/space-age/space_age_test.rb (100%) rename exercises/{ => practice}/strain/.meta/solutions/strain.rb (100%) rename exercises/{ => practice}/strain/README.md (100%) rename exercises/{ => practice}/strain/strain.rb (100%) rename exercises/{ => practice}/strain/strain_test.rb (100%) rename exercises/{ => practice}/sum-of-multiples/.meta/generator/sum_of_multiples_case.rb (100%) rename exercises/{ => practice}/sum-of-multiples/.meta/solutions/sum_of_multiples.rb (100%) rename exercises/{ => practice}/sum-of-multiples/.meta/tests.toml (100%) rename exercises/{ => practice}/sum-of-multiples/README.md (100%) rename exercises/{ => practice}/sum-of-multiples/sum_of_multiples.rb (100%) rename exercises/{ => practice}/sum-of-multiples/sum_of_multiples_test.rb (100%) rename exercises/{ => practice}/tournament/.meta/generator/tournament_case.rb (100%) rename exercises/{ => practice}/tournament/.meta/solutions/tournament.rb (100%) rename exercises/{ => practice}/tournament/.meta/tests.toml (100%) rename exercises/{ => practice}/tournament/README.md (100%) rename exercises/{ => practice}/tournament/tournament.rb (100%) rename exercises/{ => practice}/tournament/tournament_test.rb (100%) rename exercises/{ => practice}/transpose/.meta/generator/transpose_case.rb (100%) rename exercises/{ => practice}/transpose/.meta/solutions/transpose.rb (100%) rename exercises/{ => practice}/transpose/.meta/tests.toml (100%) rename exercises/{ => practice}/transpose/README.md (100%) rename exercises/{ => practice}/transpose/transpose.rb (100%) rename exercises/{ => practice}/transpose/transpose_test.rb (100%) rename exercises/{ => practice}/triangle/.meta/generator/triangle_case.rb (100%) rename exercises/{ => practice}/triangle/.meta/solutions/triangle.rb (100%) rename exercises/{ => practice}/triangle/.meta/tests.toml (100%) rename exercises/{ => practice}/triangle/README.md (100%) rename exercises/{ => practice}/triangle/triangle.rb (100%) rename exercises/{ => practice}/triangle/triangle_test.rb (100%) rename exercises/{ => practice}/trinary/.meta/solutions/trinary.rb (100%) rename exercises/{ => practice}/trinary/.meta/tests.toml (100%) rename exercises/{ => practice}/trinary/README.md (100%) rename exercises/{ => practice}/trinary/trinary.rb (100%) rename exercises/{ => practice}/trinary/trinary_test.rb (100%) rename exercises/{ => practice}/twelve-days/.meta/solutions/twelve_days.rb (100%) rename exercises/{ => practice}/twelve-days/.meta/tests.toml (100%) rename exercises/{ => practice}/twelve-days/README.md (100%) rename exercises/{ => practice}/twelve-days/song.txt (100%) rename exercises/{ => practice}/twelve-days/twelve_days.rb (100%) rename exercises/{ => practice}/twelve-days/twelve_days_test.rb (100%) rename exercises/{ => practice}/two-bucket/.meta/generator/two_bucket_case.rb (100%) rename exercises/{ => practice}/two-bucket/.meta/solutions/two_bucket.rb (100%) rename exercises/{ => practice}/two-bucket/.meta/tests.toml (100%) rename exercises/{ => practice}/two-bucket/README.md (100%) rename exercises/{ => practice}/two-bucket/two_bucket.rb (100%) rename exercises/{ => practice}/two-bucket/two_bucket_test.rb (100%) rename exercises/{ => practice}/two-fer/.meta/generator/two_fer_case.rb (100%) rename exercises/{ => practice}/two-fer/.meta/solutions/two_fer.rb (100%) rename exercises/{ => practice}/two-fer/.meta/tests.toml (100%) rename exercises/{ => practice}/two-fer/README.md (100%) rename exercises/{ => practice}/two-fer/two_fer.rb (100%) rename exercises/{ => practice}/two-fer/two_fer_test.rb (100%) rename exercises/{ => practice}/word-count/.meta/generator/word_count_case.rb (100%) rename exercises/{ => practice}/word-count/.meta/solutions/word_count.rb (100%) rename exercises/{ => practice}/word-count/.meta/tests.toml (100%) rename exercises/{ => practice}/word-count/README.md (100%) rename exercises/{ => practice}/word-count/word_count.rb (100%) rename exercises/{ => practice}/word-count/word_count_test.rb (100%) rename exercises/{ => practice}/wordy/.meta/generator/wordy_case.rb (100%) rename exercises/{ => practice}/wordy/.meta/solutions/wordy.rb (100%) rename exercises/{ => practice}/wordy/.meta/tests.toml (100%) rename exercises/{ => practice}/wordy/README.md (100%) rename exercises/{ => practice}/wordy/wordy.rb (100%) rename exercises/{ => practice}/wordy/wordy_test.rb (100%) rename exercises/{ => practice}/zipper/.meta/generator/zipper_case.rb (100%) rename exercises/{ => practice}/zipper/.meta/solutions/zipper.rb (100%) rename exercises/{ => practice}/zipper/.meta/tests.toml (100%) rename exercises/{ => practice}/zipper/README.md (100%) rename exercises/{ => practice}/zipper/zipper.rb (100%) rename exercises/{ => practice}/zipper/zipper_test.rb (100%) diff --git a/exercises/accumulate/.meta/hints.md b/exercises/practice/accumulate/.meta/hints.md similarity index 100% rename from exercises/accumulate/.meta/hints.md rename to exercises/practice/accumulate/.meta/hints.md diff --git a/exercises/accumulate/.meta/solutions/accumulate.rb b/exercises/practice/accumulate/.meta/solutions/accumulate.rb similarity index 100% rename from exercises/accumulate/.meta/solutions/accumulate.rb rename to exercises/practice/accumulate/.meta/solutions/accumulate.rb diff --git a/exercises/accumulate/README.md b/exercises/practice/accumulate/README.md similarity index 100% rename from exercises/accumulate/README.md rename to exercises/practice/accumulate/README.md diff --git a/exercises/accumulate/accumulate.rb b/exercises/practice/accumulate/accumulate.rb similarity index 100% rename from exercises/accumulate/accumulate.rb rename to exercises/practice/accumulate/accumulate.rb diff --git a/exercises/accumulate/accumulate_test.rb b/exercises/practice/accumulate/accumulate_test.rb similarity index 100% rename from exercises/accumulate/accumulate_test.rb rename to exercises/practice/accumulate/accumulate_test.rb diff --git a/exercises/acronym/.meta/generator/acronym_case.rb b/exercises/practice/acronym/.meta/generator/acronym_case.rb similarity index 100% rename from exercises/acronym/.meta/generator/acronym_case.rb rename to exercises/practice/acronym/.meta/generator/acronym_case.rb diff --git a/exercises/acronym/.meta/solutions/acronym.rb b/exercises/practice/acronym/.meta/solutions/acronym.rb similarity index 100% rename from exercises/acronym/.meta/solutions/acronym.rb rename to exercises/practice/acronym/.meta/solutions/acronym.rb diff --git a/exercises/acronym/.meta/tests.toml b/exercises/practice/acronym/.meta/tests.toml similarity index 100% rename from exercises/acronym/.meta/tests.toml rename to exercises/practice/acronym/.meta/tests.toml diff --git a/exercises/acronym/README.md b/exercises/practice/acronym/README.md similarity index 100% rename from exercises/acronym/README.md rename to exercises/practice/acronym/README.md diff --git a/exercises/acronym/acronym.rb b/exercises/practice/acronym/acronym.rb similarity index 100% rename from exercises/acronym/acronym.rb rename to exercises/practice/acronym/acronym.rb diff --git a/exercises/acronym/acronym_test.rb b/exercises/practice/acronym/acronym_test.rb similarity index 100% rename from exercises/acronym/acronym_test.rb rename to exercises/practice/acronym/acronym_test.rb diff --git a/exercises/affine-cipher/.meta/generator/affine_cipher_case.rb b/exercises/practice/affine-cipher/.meta/generator/affine_cipher_case.rb similarity index 100% rename from exercises/affine-cipher/.meta/generator/affine_cipher_case.rb rename to exercises/practice/affine-cipher/.meta/generator/affine_cipher_case.rb diff --git a/exercises/affine-cipher/.meta/solutions/affine_cipher.rb b/exercises/practice/affine-cipher/.meta/solutions/affine_cipher.rb similarity index 100% rename from exercises/affine-cipher/.meta/solutions/affine_cipher.rb rename to exercises/practice/affine-cipher/.meta/solutions/affine_cipher.rb diff --git a/exercises/affine-cipher/.meta/tests.toml b/exercises/practice/affine-cipher/.meta/tests.toml similarity index 100% rename from exercises/affine-cipher/.meta/tests.toml rename to exercises/practice/affine-cipher/.meta/tests.toml diff --git a/exercises/affine-cipher/README.md b/exercises/practice/affine-cipher/README.md similarity index 100% rename from exercises/affine-cipher/README.md rename to exercises/practice/affine-cipher/README.md diff --git a/exercises/affine-cipher/affine_cipher.rb b/exercises/practice/affine-cipher/affine_cipher.rb similarity index 100% rename from exercises/affine-cipher/affine_cipher.rb rename to exercises/practice/affine-cipher/affine_cipher.rb diff --git a/exercises/affine-cipher/affine_cipher_test.rb b/exercises/practice/affine-cipher/affine_cipher_test.rb similarity index 100% rename from exercises/affine-cipher/affine_cipher_test.rb rename to exercises/practice/affine-cipher/affine_cipher_test.rb diff --git a/exercises/all-your-base/.meta/generator/all_your_base_case.rb b/exercises/practice/all-your-base/.meta/generator/all_your_base_case.rb similarity index 100% rename from exercises/all-your-base/.meta/generator/all_your_base_case.rb rename to exercises/practice/all-your-base/.meta/generator/all_your_base_case.rb diff --git a/exercises/all-your-base/.meta/solutions/all_your_base.rb b/exercises/practice/all-your-base/.meta/solutions/all_your_base.rb similarity index 100% rename from exercises/all-your-base/.meta/solutions/all_your_base.rb rename to exercises/practice/all-your-base/.meta/solutions/all_your_base.rb diff --git a/exercises/all-your-base/.meta/tests.toml b/exercises/practice/all-your-base/.meta/tests.toml similarity index 100% rename from exercises/all-your-base/.meta/tests.toml rename to exercises/practice/all-your-base/.meta/tests.toml diff --git a/exercises/all-your-base/README.md b/exercises/practice/all-your-base/README.md similarity index 100% rename from exercises/all-your-base/README.md rename to exercises/practice/all-your-base/README.md diff --git a/exercises/all-your-base/all_your_base.rb b/exercises/practice/all-your-base/all_your_base.rb similarity index 100% rename from exercises/all-your-base/all_your_base.rb rename to exercises/practice/all-your-base/all_your_base.rb diff --git a/exercises/all-your-base/all_your_base_test.rb b/exercises/practice/all-your-base/all_your_base_test.rb similarity index 100% rename from exercises/all-your-base/all_your_base_test.rb rename to exercises/practice/all-your-base/all_your_base_test.rb diff --git a/exercises/allergies/.meta/generator/allergies_case.rb b/exercises/practice/allergies/.meta/generator/allergies_case.rb similarity index 100% rename from exercises/allergies/.meta/generator/allergies_case.rb rename to exercises/practice/allergies/.meta/generator/allergies_case.rb diff --git a/exercises/allergies/.meta/solutions/allergies.rb b/exercises/practice/allergies/.meta/solutions/allergies.rb similarity index 100% rename from exercises/allergies/.meta/solutions/allergies.rb rename to exercises/practice/allergies/.meta/solutions/allergies.rb diff --git a/exercises/allergies/.meta/tests.toml b/exercises/practice/allergies/.meta/tests.toml similarity index 100% rename from exercises/allergies/.meta/tests.toml rename to exercises/practice/allergies/.meta/tests.toml diff --git a/exercises/allergies/README.md b/exercises/practice/allergies/README.md similarity index 100% rename from exercises/allergies/README.md rename to exercises/practice/allergies/README.md diff --git a/exercises/allergies/allergies.rb b/exercises/practice/allergies/allergies.rb similarity index 100% rename from exercises/allergies/allergies.rb rename to exercises/practice/allergies/allergies.rb diff --git a/exercises/allergies/allergies_test.rb b/exercises/practice/allergies/allergies_test.rb similarity index 100% rename from exercises/allergies/allergies_test.rb rename to exercises/practice/allergies/allergies_test.rb diff --git a/exercises/alphametics/.meta/generator/alphametics_case.rb b/exercises/practice/alphametics/.meta/generator/alphametics_case.rb similarity index 100% rename from exercises/alphametics/.meta/generator/alphametics_case.rb rename to exercises/practice/alphametics/.meta/generator/alphametics_case.rb diff --git a/exercises/alphametics/.meta/solutions/alphametics.rb b/exercises/practice/alphametics/.meta/solutions/alphametics.rb similarity index 100% rename from exercises/alphametics/.meta/solutions/alphametics.rb rename to exercises/practice/alphametics/.meta/solutions/alphametics.rb diff --git a/exercises/alphametics/.meta/solutions/alphametics_compact.rb b/exercises/practice/alphametics/.meta/solutions/alphametics_compact.rb similarity index 100% rename from exercises/alphametics/.meta/solutions/alphametics_compact.rb rename to exercises/practice/alphametics/.meta/solutions/alphametics_compact.rb diff --git a/exercises/alphametics/.meta/tests.toml b/exercises/practice/alphametics/.meta/tests.toml similarity index 100% rename from exercises/alphametics/.meta/tests.toml rename to exercises/practice/alphametics/.meta/tests.toml diff --git a/exercises/alphametics/README.md b/exercises/practice/alphametics/README.md similarity index 100% rename from exercises/alphametics/README.md rename to exercises/practice/alphametics/README.md diff --git a/exercises/alphametics/alphametics.rb b/exercises/practice/alphametics/alphametics.rb similarity index 100% rename from exercises/alphametics/alphametics.rb rename to exercises/practice/alphametics/alphametics.rb diff --git a/exercises/alphametics/alphametics_test.rb b/exercises/practice/alphametics/alphametics_test.rb similarity index 100% rename from exercises/alphametics/alphametics_test.rb rename to exercises/practice/alphametics/alphametics_test.rb diff --git a/exercises/anagram/.meta/generator/anagram_case.rb b/exercises/practice/anagram/.meta/generator/anagram_case.rb similarity index 100% rename from exercises/anagram/.meta/generator/anagram_case.rb rename to exercises/practice/anagram/.meta/generator/anagram_case.rb diff --git a/exercises/anagram/.meta/solutions/anagram.rb b/exercises/practice/anagram/.meta/solutions/anagram.rb similarity index 100% rename from exercises/anagram/.meta/solutions/anagram.rb rename to exercises/practice/anagram/.meta/solutions/anagram.rb diff --git a/exercises/anagram/.meta/tests.toml b/exercises/practice/anagram/.meta/tests.toml similarity index 100% rename from exercises/anagram/.meta/tests.toml rename to exercises/practice/anagram/.meta/tests.toml diff --git a/exercises/anagram/README.md b/exercises/practice/anagram/README.md similarity index 100% rename from exercises/anagram/README.md rename to exercises/practice/anagram/README.md diff --git a/exercises/anagram/anagram.rb b/exercises/practice/anagram/anagram.rb similarity index 100% rename from exercises/anagram/anagram.rb rename to exercises/practice/anagram/anagram.rb diff --git a/exercises/anagram/anagram_test.rb b/exercises/practice/anagram/anagram_test.rb similarity index 100% rename from exercises/anagram/anagram_test.rb rename to exercises/practice/anagram/anagram_test.rb diff --git a/exercises/armstrong-numbers/.meta/generator/armstrong_numbers_case.rb b/exercises/practice/armstrong-numbers/.meta/generator/armstrong_numbers_case.rb similarity index 100% rename from exercises/armstrong-numbers/.meta/generator/armstrong_numbers_case.rb rename to exercises/practice/armstrong-numbers/.meta/generator/armstrong_numbers_case.rb diff --git a/exercises/armstrong-numbers/.meta/solutions/armstrong_numbers.rb b/exercises/practice/armstrong-numbers/.meta/solutions/armstrong_numbers.rb similarity index 100% rename from exercises/armstrong-numbers/.meta/solutions/armstrong_numbers.rb rename to exercises/practice/armstrong-numbers/.meta/solutions/armstrong_numbers.rb diff --git a/exercises/armstrong-numbers/.meta/tests.toml b/exercises/practice/armstrong-numbers/.meta/tests.toml similarity index 100% rename from exercises/armstrong-numbers/.meta/tests.toml rename to exercises/practice/armstrong-numbers/.meta/tests.toml diff --git a/exercises/armstrong-numbers/README.md b/exercises/practice/armstrong-numbers/README.md similarity index 100% rename from exercises/armstrong-numbers/README.md rename to exercises/practice/armstrong-numbers/README.md diff --git a/exercises/armstrong-numbers/armstrong_numbers.rb b/exercises/practice/armstrong-numbers/armstrong_numbers.rb similarity index 100% rename from exercises/armstrong-numbers/armstrong_numbers.rb rename to exercises/practice/armstrong-numbers/armstrong_numbers.rb diff --git a/exercises/armstrong-numbers/armstrong_numbers_test.rb b/exercises/practice/armstrong-numbers/armstrong_numbers_test.rb similarity index 100% rename from exercises/armstrong-numbers/armstrong_numbers_test.rb rename to exercises/practice/armstrong-numbers/armstrong_numbers_test.rb diff --git a/exercises/atbash-cipher/.meta/generator/atbash_cipher_case.rb b/exercises/practice/atbash-cipher/.meta/generator/atbash_cipher_case.rb similarity index 100% rename from exercises/atbash-cipher/.meta/generator/atbash_cipher_case.rb rename to exercises/practice/atbash-cipher/.meta/generator/atbash_cipher_case.rb diff --git a/exercises/atbash-cipher/.meta/solutions/atbash_cipher.rb b/exercises/practice/atbash-cipher/.meta/solutions/atbash_cipher.rb similarity index 100% rename from exercises/atbash-cipher/.meta/solutions/atbash_cipher.rb rename to exercises/practice/atbash-cipher/.meta/solutions/atbash_cipher.rb diff --git a/exercises/atbash-cipher/.meta/tests.toml b/exercises/practice/atbash-cipher/.meta/tests.toml similarity index 100% rename from exercises/atbash-cipher/.meta/tests.toml rename to exercises/practice/atbash-cipher/.meta/tests.toml diff --git a/exercises/atbash-cipher/README.md b/exercises/practice/atbash-cipher/README.md similarity index 100% rename from exercises/atbash-cipher/README.md rename to exercises/practice/atbash-cipher/README.md diff --git a/exercises/atbash-cipher/atbash_cipher.rb b/exercises/practice/atbash-cipher/atbash_cipher.rb similarity index 100% rename from exercises/atbash-cipher/atbash_cipher.rb rename to exercises/practice/atbash-cipher/atbash_cipher.rb diff --git a/exercises/atbash-cipher/atbash_cipher_test.rb b/exercises/practice/atbash-cipher/atbash_cipher_test.rb similarity index 100% rename from exercises/atbash-cipher/atbash_cipher_test.rb rename to exercises/practice/atbash-cipher/atbash_cipher_test.rb diff --git a/exercises/beer-song/.meta/generator/beer_song_case.rb b/exercises/practice/beer-song/.meta/generator/beer_song_case.rb similarity index 100% rename from exercises/beer-song/.meta/generator/beer_song_case.rb rename to exercises/practice/beer-song/.meta/generator/beer_song_case.rb diff --git a/exercises/beer-song/.meta/solutions/beer_song.rb b/exercises/practice/beer-song/.meta/solutions/beer_song.rb similarity index 100% rename from exercises/beer-song/.meta/solutions/beer_song.rb rename to exercises/practice/beer-song/.meta/solutions/beer_song.rb diff --git a/exercises/beer-song/.meta/tests.toml b/exercises/practice/beer-song/.meta/tests.toml similarity index 100% rename from exercises/beer-song/.meta/tests.toml rename to exercises/practice/beer-song/.meta/tests.toml diff --git a/exercises/beer-song/README.md b/exercises/practice/beer-song/README.md similarity index 100% rename from exercises/beer-song/README.md rename to exercises/practice/beer-song/README.md diff --git a/exercises/beer-song/beer_song.rb b/exercises/practice/beer-song/beer_song.rb similarity index 100% rename from exercises/beer-song/beer_song.rb rename to exercises/practice/beer-song/beer_song.rb diff --git a/exercises/beer-song/beer_song_test.rb b/exercises/practice/beer-song/beer_song_test.rb similarity index 100% rename from exercises/beer-song/beer_song_test.rb rename to exercises/practice/beer-song/beer_song_test.rb diff --git a/exercises/binary-search-tree/.meta/solutions/binary_search_tree.rb b/exercises/practice/binary-search-tree/.meta/solutions/binary_search_tree.rb similarity index 100% rename from exercises/binary-search-tree/.meta/solutions/binary_search_tree.rb rename to exercises/practice/binary-search-tree/.meta/solutions/binary_search_tree.rb diff --git a/exercises/binary-search-tree/.meta/tests.toml b/exercises/practice/binary-search-tree/.meta/tests.toml similarity index 100% rename from exercises/binary-search-tree/.meta/tests.toml rename to exercises/practice/binary-search-tree/.meta/tests.toml diff --git a/exercises/binary-search-tree/README.md b/exercises/practice/binary-search-tree/README.md similarity index 100% rename from exercises/binary-search-tree/README.md rename to exercises/practice/binary-search-tree/README.md diff --git a/exercises/binary-search-tree/binary_search_tree.rb b/exercises/practice/binary-search-tree/binary_search_tree.rb similarity index 100% rename from exercises/binary-search-tree/binary_search_tree.rb rename to exercises/practice/binary-search-tree/binary_search_tree.rb diff --git a/exercises/binary-search-tree/binary_search_tree_test.rb b/exercises/practice/binary-search-tree/binary_search_tree_test.rb similarity index 100% rename from exercises/binary-search-tree/binary_search_tree_test.rb rename to exercises/practice/binary-search-tree/binary_search_tree_test.rb diff --git a/exercises/binary-search/.meta/generator/binary_search_case.rb b/exercises/practice/binary-search/.meta/generator/binary_search_case.rb similarity index 100% rename from exercises/binary-search/.meta/generator/binary_search_case.rb rename to exercises/practice/binary-search/.meta/generator/binary_search_case.rb diff --git a/exercises/binary-search/.meta/solutions/binary_search.rb b/exercises/practice/binary-search/.meta/solutions/binary_search.rb similarity index 100% rename from exercises/binary-search/.meta/solutions/binary_search.rb rename to exercises/practice/binary-search/.meta/solutions/binary_search.rb diff --git a/exercises/binary-search/.meta/tests.toml b/exercises/practice/binary-search/.meta/tests.toml similarity index 100% rename from exercises/binary-search/.meta/tests.toml rename to exercises/practice/binary-search/.meta/tests.toml diff --git a/exercises/binary-search/README.md b/exercises/practice/binary-search/README.md similarity index 100% rename from exercises/binary-search/README.md rename to exercises/practice/binary-search/README.md diff --git a/exercises/binary-search/binary_search.rb b/exercises/practice/binary-search/binary_search.rb similarity index 100% rename from exercises/binary-search/binary_search.rb rename to exercises/practice/binary-search/binary_search.rb diff --git a/exercises/binary-search/binary_search_test.rb b/exercises/practice/binary-search/binary_search_test.rb similarity index 100% rename from exercises/binary-search/binary_search_test.rb rename to exercises/practice/binary-search/binary_search_test.rb diff --git a/exercises/binary/.meta/generator/binary_case.rb b/exercises/practice/binary/.meta/generator/binary_case.rb similarity index 100% rename from exercises/binary/.meta/generator/binary_case.rb rename to exercises/practice/binary/.meta/generator/binary_case.rb diff --git a/exercises/binary/.meta/solutions/binary.rb b/exercises/practice/binary/.meta/solutions/binary.rb similarity index 100% rename from exercises/binary/.meta/solutions/binary.rb rename to exercises/practice/binary/.meta/solutions/binary.rb diff --git a/exercises/binary/.meta/tests.toml b/exercises/practice/binary/.meta/tests.toml similarity index 100% rename from exercises/binary/.meta/tests.toml rename to exercises/practice/binary/.meta/tests.toml diff --git a/exercises/binary/README.md b/exercises/practice/binary/README.md similarity index 100% rename from exercises/binary/README.md rename to exercises/practice/binary/README.md diff --git a/exercises/binary/binary.rb b/exercises/practice/binary/binary.rb similarity index 100% rename from exercises/binary/binary.rb rename to exercises/practice/binary/binary.rb diff --git a/exercises/binary/binary_test.rb b/exercises/practice/binary/binary_test.rb similarity index 100% rename from exercises/binary/binary_test.rb rename to exercises/practice/binary/binary_test.rb diff --git a/exercises/bob/.meta/generator/bob_case.rb b/exercises/practice/bob/.meta/generator/bob_case.rb similarity index 100% rename from exercises/bob/.meta/generator/bob_case.rb rename to exercises/practice/bob/.meta/generator/bob_case.rb diff --git a/exercises/bob/.meta/solutions/bob.rb b/exercises/practice/bob/.meta/solutions/bob.rb similarity index 100% rename from exercises/bob/.meta/solutions/bob.rb rename to exercises/practice/bob/.meta/solutions/bob.rb diff --git a/exercises/bob/.meta/tests.toml b/exercises/practice/bob/.meta/tests.toml similarity index 100% rename from exercises/bob/.meta/tests.toml rename to exercises/practice/bob/.meta/tests.toml diff --git a/exercises/bob/README.md b/exercises/practice/bob/README.md similarity index 100% rename from exercises/bob/README.md rename to exercises/practice/bob/README.md diff --git a/exercises/bob/bob.rb b/exercises/practice/bob/bob.rb similarity index 100% rename from exercises/bob/bob.rb rename to exercises/practice/bob/bob.rb diff --git a/exercises/bob/bob_test.rb b/exercises/practice/bob/bob_test.rb similarity index 100% rename from exercises/bob/bob_test.rb rename to exercises/practice/bob/bob_test.rb diff --git a/exercises/book-store/.meta/generator/book_store_case.rb b/exercises/practice/book-store/.meta/generator/book_store_case.rb similarity index 100% rename from exercises/book-store/.meta/generator/book_store_case.rb rename to exercises/practice/book-store/.meta/generator/book_store_case.rb diff --git a/exercises/book-store/.meta/solutions/book_store.rb b/exercises/practice/book-store/.meta/solutions/book_store.rb similarity index 100% rename from exercises/book-store/.meta/solutions/book_store.rb rename to exercises/practice/book-store/.meta/solutions/book_store.rb diff --git a/exercises/book-store/.meta/tests.toml b/exercises/practice/book-store/.meta/tests.toml similarity index 100% rename from exercises/book-store/.meta/tests.toml rename to exercises/practice/book-store/.meta/tests.toml diff --git a/exercises/book-store/README.md b/exercises/practice/book-store/README.md similarity index 100% rename from exercises/book-store/README.md rename to exercises/practice/book-store/README.md diff --git a/exercises/book-store/book_store.rb b/exercises/practice/book-store/book_store.rb similarity index 100% rename from exercises/book-store/book_store.rb rename to exercises/practice/book-store/book_store.rb diff --git a/exercises/book-store/book_store_test.rb b/exercises/practice/book-store/book_store_test.rb similarity index 100% rename from exercises/book-store/book_store_test.rb rename to exercises/practice/book-store/book_store_test.rb diff --git a/exercises/bowling/.meta/generator/bowling_case.rb b/exercises/practice/bowling/.meta/generator/bowling_case.rb similarity index 100% rename from exercises/bowling/.meta/generator/bowling_case.rb rename to exercises/practice/bowling/.meta/generator/bowling_case.rb diff --git a/exercises/bowling/.meta/solutions/bowling.rb b/exercises/practice/bowling/.meta/solutions/bowling.rb similarity index 100% rename from exercises/bowling/.meta/solutions/bowling.rb rename to exercises/practice/bowling/.meta/solutions/bowling.rb diff --git a/exercises/bowling/.meta/tests.toml b/exercises/practice/bowling/.meta/tests.toml similarity index 100% rename from exercises/bowling/.meta/tests.toml rename to exercises/practice/bowling/.meta/tests.toml diff --git a/exercises/bowling/README.md b/exercises/practice/bowling/README.md similarity index 100% rename from exercises/bowling/README.md rename to exercises/practice/bowling/README.md diff --git a/exercises/bowling/bowling.rb b/exercises/practice/bowling/bowling.rb similarity index 100% rename from exercises/bowling/bowling.rb rename to exercises/practice/bowling/bowling.rb diff --git a/exercises/bowling/bowling_test.rb b/exercises/practice/bowling/bowling_test.rb similarity index 100% rename from exercises/bowling/bowling_test.rb rename to exercises/practice/bowling/bowling_test.rb diff --git a/exercises/change/.meta/generator/change_case.rb b/exercises/practice/change/.meta/generator/change_case.rb similarity index 100% rename from exercises/change/.meta/generator/change_case.rb rename to exercises/practice/change/.meta/generator/change_case.rb diff --git a/exercises/change/.meta/solutions/change.rb b/exercises/practice/change/.meta/solutions/change.rb similarity index 100% rename from exercises/change/.meta/solutions/change.rb rename to exercises/practice/change/.meta/solutions/change.rb diff --git a/exercises/change/.meta/tests.toml b/exercises/practice/change/.meta/tests.toml similarity index 100% rename from exercises/change/.meta/tests.toml rename to exercises/practice/change/.meta/tests.toml diff --git a/exercises/change/README.md b/exercises/practice/change/README.md similarity index 100% rename from exercises/change/README.md rename to exercises/practice/change/README.md diff --git a/exercises/change/change.rb b/exercises/practice/change/change.rb similarity index 100% rename from exercises/change/change.rb rename to exercises/practice/change/change.rb diff --git a/exercises/change/change_test.rb b/exercises/practice/change/change_test.rb similarity index 100% rename from exercises/change/change_test.rb rename to exercises/practice/change/change_test.rb diff --git a/exercises/circular-buffer/.meta/solutions/circular_buffer.rb b/exercises/practice/circular-buffer/.meta/solutions/circular_buffer.rb similarity index 100% rename from exercises/circular-buffer/.meta/solutions/circular_buffer.rb rename to exercises/practice/circular-buffer/.meta/solutions/circular_buffer.rb diff --git a/exercises/circular-buffer/.meta/tests.toml b/exercises/practice/circular-buffer/.meta/tests.toml similarity index 100% rename from exercises/circular-buffer/.meta/tests.toml rename to exercises/practice/circular-buffer/.meta/tests.toml diff --git a/exercises/circular-buffer/README.md b/exercises/practice/circular-buffer/README.md similarity index 100% rename from exercises/circular-buffer/README.md rename to exercises/practice/circular-buffer/README.md diff --git a/exercises/circular-buffer/circular_buffer.rb b/exercises/practice/circular-buffer/circular_buffer.rb similarity index 100% rename from exercises/circular-buffer/circular_buffer.rb rename to exercises/practice/circular-buffer/circular_buffer.rb diff --git a/exercises/circular-buffer/circular_buffer_test.rb b/exercises/practice/circular-buffer/circular_buffer_test.rb similarity index 100% rename from exercises/circular-buffer/circular_buffer_test.rb rename to exercises/practice/circular-buffer/circular_buffer_test.rb diff --git a/exercises/clock/.meta/generator/clock_case.rb b/exercises/practice/clock/.meta/generator/clock_case.rb similarity index 100% rename from exercises/clock/.meta/generator/clock_case.rb rename to exercises/practice/clock/.meta/generator/clock_case.rb diff --git a/exercises/clock/.meta/solutions/clock.rb b/exercises/practice/clock/.meta/solutions/clock.rb similarity index 100% rename from exercises/clock/.meta/solutions/clock.rb rename to exercises/practice/clock/.meta/solutions/clock.rb diff --git a/exercises/clock/.meta/tests.toml b/exercises/practice/clock/.meta/tests.toml similarity index 100% rename from exercises/clock/.meta/tests.toml rename to exercises/practice/clock/.meta/tests.toml diff --git a/exercises/clock/README.md b/exercises/practice/clock/README.md similarity index 100% rename from exercises/clock/README.md rename to exercises/practice/clock/README.md diff --git a/exercises/clock/clock.rb b/exercises/practice/clock/clock.rb similarity index 100% rename from exercises/clock/clock.rb rename to exercises/practice/clock/clock.rb diff --git a/exercises/clock/clock_test.rb b/exercises/practice/clock/clock_test.rb similarity index 100% rename from exercises/clock/clock_test.rb rename to exercises/practice/clock/clock_test.rb diff --git a/exercises/collatz-conjecture/.meta/generator/collatz_conjecture_case.rb b/exercises/practice/collatz-conjecture/.meta/generator/collatz_conjecture_case.rb similarity index 100% rename from exercises/collatz-conjecture/.meta/generator/collatz_conjecture_case.rb rename to exercises/practice/collatz-conjecture/.meta/generator/collatz_conjecture_case.rb diff --git a/exercises/collatz-conjecture/.meta/solutions/collatz_conjecture.rb b/exercises/practice/collatz-conjecture/.meta/solutions/collatz_conjecture.rb similarity index 100% rename from exercises/collatz-conjecture/.meta/solutions/collatz_conjecture.rb rename to exercises/practice/collatz-conjecture/.meta/solutions/collatz_conjecture.rb diff --git a/exercises/collatz-conjecture/.meta/tests.toml b/exercises/practice/collatz-conjecture/.meta/tests.toml similarity index 100% rename from exercises/collatz-conjecture/.meta/tests.toml rename to exercises/practice/collatz-conjecture/.meta/tests.toml diff --git a/exercises/collatz-conjecture/README.md b/exercises/practice/collatz-conjecture/README.md similarity index 100% rename from exercises/collatz-conjecture/README.md rename to exercises/practice/collatz-conjecture/README.md diff --git a/exercises/collatz-conjecture/collatz_conjecture.rb b/exercises/practice/collatz-conjecture/collatz_conjecture.rb similarity index 100% rename from exercises/collatz-conjecture/collatz_conjecture.rb rename to exercises/practice/collatz-conjecture/collatz_conjecture.rb diff --git a/exercises/collatz-conjecture/collatz_conjecture_test.rb b/exercises/practice/collatz-conjecture/collatz_conjecture_test.rb similarity index 100% rename from exercises/collatz-conjecture/collatz_conjecture_test.rb rename to exercises/practice/collatz-conjecture/collatz_conjecture_test.rb diff --git a/exercises/complex-numbers/.meta/generator/complex_numbers_case.rb b/exercises/practice/complex-numbers/.meta/generator/complex_numbers_case.rb similarity index 100% rename from exercises/complex-numbers/.meta/generator/complex_numbers_case.rb rename to exercises/practice/complex-numbers/.meta/generator/complex_numbers_case.rb diff --git a/exercises/complex-numbers/.meta/solutions/complex_numbers.rb b/exercises/practice/complex-numbers/.meta/solutions/complex_numbers.rb similarity index 100% rename from exercises/complex-numbers/.meta/solutions/complex_numbers.rb rename to exercises/practice/complex-numbers/.meta/solutions/complex_numbers.rb diff --git a/exercises/complex-numbers/.meta/tests.toml b/exercises/practice/complex-numbers/.meta/tests.toml similarity index 100% rename from exercises/complex-numbers/.meta/tests.toml rename to exercises/practice/complex-numbers/.meta/tests.toml diff --git a/exercises/complex-numbers/README.md b/exercises/practice/complex-numbers/README.md similarity index 100% rename from exercises/complex-numbers/README.md rename to exercises/practice/complex-numbers/README.md diff --git a/exercises/complex-numbers/complex_numbers.rb b/exercises/practice/complex-numbers/complex_numbers.rb similarity index 100% rename from exercises/complex-numbers/complex_numbers.rb rename to exercises/practice/complex-numbers/complex_numbers.rb diff --git a/exercises/complex-numbers/complex_numbers_test.rb b/exercises/practice/complex-numbers/complex_numbers_test.rb similarity index 100% rename from exercises/complex-numbers/complex_numbers_test.rb rename to exercises/practice/complex-numbers/complex_numbers_test.rb diff --git a/exercises/connect/.meta/generator/connect_case.rb b/exercises/practice/connect/.meta/generator/connect_case.rb similarity index 100% rename from exercises/connect/.meta/generator/connect_case.rb rename to exercises/practice/connect/.meta/generator/connect_case.rb diff --git a/exercises/connect/.meta/solutions/connect.rb b/exercises/practice/connect/.meta/solutions/connect.rb similarity index 100% rename from exercises/connect/.meta/solutions/connect.rb rename to exercises/practice/connect/.meta/solutions/connect.rb diff --git a/exercises/connect/.meta/tests.toml b/exercises/practice/connect/.meta/tests.toml similarity index 100% rename from exercises/connect/.meta/tests.toml rename to exercises/practice/connect/.meta/tests.toml diff --git a/exercises/connect/README.md b/exercises/practice/connect/README.md similarity index 100% rename from exercises/connect/README.md rename to exercises/practice/connect/README.md diff --git a/exercises/connect/connect.rb b/exercises/practice/connect/connect.rb similarity index 100% rename from exercises/connect/connect.rb rename to exercises/practice/connect/connect.rb diff --git a/exercises/connect/connect_test.rb b/exercises/practice/connect/connect_test.rb similarity index 100% rename from exercises/connect/connect_test.rb rename to exercises/practice/connect/connect_test.rb diff --git a/exercises/crypto-square/.meta/generator/crypto_square_case.rb b/exercises/practice/crypto-square/.meta/generator/crypto_square_case.rb similarity index 100% rename from exercises/crypto-square/.meta/generator/crypto_square_case.rb rename to exercises/practice/crypto-square/.meta/generator/crypto_square_case.rb diff --git a/exercises/crypto-square/.meta/solutions/crypto_square.rb b/exercises/practice/crypto-square/.meta/solutions/crypto_square.rb similarity index 100% rename from exercises/crypto-square/.meta/solutions/crypto_square.rb rename to exercises/practice/crypto-square/.meta/solutions/crypto_square.rb diff --git a/exercises/crypto-square/.meta/tests.toml b/exercises/practice/crypto-square/.meta/tests.toml similarity index 100% rename from exercises/crypto-square/.meta/tests.toml rename to exercises/practice/crypto-square/.meta/tests.toml diff --git a/exercises/crypto-square/README.md b/exercises/practice/crypto-square/README.md similarity index 100% rename from exercises/crypto-square/README.md rename to exercises/practice/crypto-square/README.md diff --git a/exercises/crypto-square/crypto_square.rb b/exercises/practice/crypto-square/crypto_square.rb similarity index 100% rename from exercises/crypto-square/crypto_square.rb rename to exercises/practice/crypto-square/crypto_square.rb diff --git a/exercises/crypto-square/crypto_square_test.rb b/exercises/practice/crypto-square/crypto_square_test.rb similarity index 100% rename from exercises/crypto-square/crypto_square_test.rb rename to exercises/practice/crypto-square/crypto_square_test.rb diff --git a/exercises/custom-set/.meta/generator/custom_set_case.rb b/exercises/practice/custom-set/.meta/generator/custom_set_case.rb similarity index 100% rename from exercises/custom-set/.meta/generator/custom_set_case.rb rename to exercises/practice/custom-set/.meta/generator/custom_set_case.rb diff --git a/exercises/custom-set/.meta/solutions/custom_set.rb b/exercises/practice/custom-set/.meta/solutions/custom_set.rb similarity index 100% rename from exercises/custom-set/.meta/solutions/custom_set.rb rename to exercises/practice/custom-set/.meta/solutions/custom_set.rb diff --git a/exercises/custom-set/.meta/tests.toml b/exercises/practice/custom-set/.meta/tests.toml similarity index 100% rename from exercises/custom-set/.meta/tests.toml rename to exercises/practice/custom-set/.meta/tests.toml diff --git a/exercises/custom-set/README.md b/exercises/practice/custom-set/README.md similarity index 100% rename from exercises/custom-set/README.md rename to exercises/practice/custom-set/README.md diff --git a/exercises/custom-set/custom_set.rb b/exercises/practice/custom-set/custom_set.rb similarity index 100% rename from exercises/custom-set/custom_set.rb rename to exercises/practice/custom-set/custom_set.rb diff --git a/exercises/custom-set/custom_set_test.rb b/exercises/practice/custom-set/custom_set_test.rb similarity index 100% rename from exercises/custom-set/custom_set_test.rb rename to exercises/practice/custom-set/custom_set_test.rb diff --git a/exercises/darts/.meta/generator/darts_case.rb b/exercises/practice/darts/.meta/generator/darts_case.rb similarity index 100% rename from exercises/darts/.meta/generator/darts_case.rb rename to exercises/practice/darts/.meta/generator/darts_case.rb diff --git a/exercises/darts/.meta/solutions/darts.rb b/exercises/practice/darts/.meta/solutions/darts.rb similarity index 100% rename from exercises/darts/.meta/solutions/darts.rb rename to exercises/practice/darts/.meta/solutions/darts.rb diff --git a/exercises/darts/.meta/tests.toml b/exercises/practice/darts/.meta/tests.toml similarity index 100% rename from exercises/darts/.meta/tests.toml rename to exercises/practice/darts/.meta/tests.toml diff --git a/exercises/darts/README.md b/exercises/practice/darts/README.md similarity index 100% rename from exercises/darts/README.md rename to exercises/practice/darts/README.md diff --git a/exercises/darts/darts.rb b/exercises/practice/darts/darts.rb similarity index 100% rename from exercises/darts/darts.rb rename to exercises/practice/darts/darts.rb diff --git a/exercises/darts/darts_test.rb b/exercises/practice/darts/darts_test.rb similarity index 100% rename from exercises/darts/darts_test.rb rename to exercises/practice/darts/darts_test.rb diff --git a/exercises/diamond/.meta/solutions/diamond.rb b/exercises/practice/diamond/.meta/solutions/diamond.rb similarity index 100% rename from exercises/diamond/.meta/solutions/diamond.rb rename to exercises/practice/diamond/.meta/solutions/diamond.rb diff --git a/exercises/diamond/.meta/tests.toml b/exercises/practice/diamond/.meta/tests.toml similarity index 100% rename from exercises/diamond/.meta/tests.toml rename to exercises/practice/diamond/.meta/tests.toml diff --git a/exercises/diamond/README.md b/exercises/practice/diamond/README.md similarity index 100% rename from exercises/diamond/README.md rename to exercises/practice/diamond/README.md diff --git a/exercises/diamond/diamond.rb b/exercises/practice/diamond/diamond.rb similarity index 100% rename from exercises/diamond/diamond.rb rename to exercises/practice/diamond/diamond.rb diff --git a/exercises/diamond/diamond_test.rb b/exercises/practice/diamond/diamond_test.rb similarity index 100% rename from exercises/diamond/diamond_test.rb rename to exercises/practice/diamond/diamond_test.rb diff --git a/exercises/difference-of-squares/.meta/generator/difference_of_squares_case.rb b/exercises/practice/difference-of-squares/.meta/generator/difference_of_squares_case.rb similarity index 100% rename from exercises/difference-of-squares/.meta/generator/difference_of_squares_case.rb rename to exercises/practice/difference-of-squares/.meta/generator/difference_of_squares_case.rb diff --git a/exercises/difference-of-squares/.meta/solutions/difference_of_squares.rb b/exercises/practice/difference-of-squares/.meta/solutions/difference_of_squares.rb similarity index 100% rename from exercises/difference-of-squares/.meta/solutions/difference_of_squares.rb rename to exercises/practice/difference-of-squares/.meta/solutions/difference_of_squares.rb diff --git a/exercises/difference-of-squares/.meta/tests.toml b/exercises/practice/difference-of-squares/.meta/tests.toml similarity index 100% rename from exercises/difference-of-squares/.meta/tests.toml rename to exercises/practice/difference-of-squares/.meta/tests.toml diff --git a/exercises/difference-of-squares/README.md b/exercises/practice/difference-of-squares/README.md similarity index 100% rename from exercises/difference-of-squares/README.md rename to exercises/practice/difference-of-squares/README.md diff --git a/exercises/difference-of-squares/difference_of_squares.rb b/exercises/practice/difference-of-squares/difference_of_squares.rb similarity index 100% rename from exercises/difference-of-squares/difference_of_squares.rb rename to exercises/practice/difference-of-squares/difference_of_squares.rb diff --git a/exercises/difference-of-squares/difference_of_squares_test.rb b/exercises/practice/difference-of-squares/difference_of_squares_test.rb similarity index 100% rename from exercises/difference-of-squares/difference_of_squares_test.rb rename to exercises/practice/difference-of-squares/difference_of_squares_test.rb diff --git a/exercises/dominoes/.meta/generator/dominoes_case.rb b/exercises/practice/dominoes/.meta/generator/dominoes_case.rb similarity index 100% rename from exercises/dominoes/.meta/generator/dominoes_case.rb rename to exercises/practice/dominoes/.meta/generator/dominoes_case.rb diff --git a/exercises/dominoes/.meta/solutions/dominoes.rb b/exercises/practice/dominoes/.meta/solutions/dominoes.rb similarity index 100% rename from exercises/dominoes/.meta/solutions/dominoes.rb rename to exercises/practice/dominoes/.meta/solutions/dominoes.rb diff --git a/exercises/dominoes/.meta/tests.toml b/exercises/practice/dominoes/.meta/tests.toml similarity index 100% rename from exercises/dominoes/.meta/tests.toml rename to exercises/practice/dominoes/.meta/tests.toml diff --git a/exercises/dominoes/README.md b/exercises/practice/dominoes/README.md similarity index 100% rename from exercises/dominoes/README.md rename to exercises/practice/dominoes/README.md diff --git a/exercises/dominoes/dominoes.rb b/exercises/practice/dominoes/dominoes.rb similarity index 100% rename from exercises/dominoes/dominoes.rb rename to exercises/practice/dominoes/dominoes.rb diff --git a/exercises/dominoes/dominoes_test.rb b/exercises/practice/dominoes/dominoes_test.rb similarity index 100% rename from exercises/dominoes/dominoes_test.rb rename to exercises/practice/dominoes/dominoes_test.rb diff --git a/exercises/etl/.meta/generator/etl_case.rb b/exercises/practice/etl/.meta/generator/etl_case.rb similarity index 100% rename from exercises/etl/.meta/generator/etl_case.rb rename to exercises/practice/etl/.meta/generator/etl_case.rb diff --git a/exercises/etl/.meta/solutions/etl.rb b/exercises/practice/etl/.meta/solutions/etl.rb similarity index 100% rename from exercises/etl/.meta/solutions/etl.rb rename to exercises/practice/etl/.meta/solutions/etl.rb diff --git a/exercises/etl/.meta/tests.toml b/exercises/practice/etl/.meta/tests.toml similarity index 100% rename from exercises/etl/.meta/tests.toml rename to exercises/practice/etl/.meta/tests.toml diff --git a/exercises/etl/README.md b/exercises/practice/etl/README.md similarity index 100% rename from exercises/etl/README.md rename to exercises/practice/etl/README.md diff --git a/exercises/etl/etl.rb b/exercises/practice/etl/etl.rb similarity index 100% rename from exercises/etl/etl.rb rename to exercises/practice/etl/etl.rb diff --git a/exercises/etl/etl_test.rb b/exercises/practice/etl/etl_test.rb similarity index 100% rename from exercises/etl/etl_test.rb rename to exercises/practice/etl/etl_test.rb diff --git a/exercises/flatten-array/.meta/generator/flatten_array_case.rb b/exercises/practice/flatten-array/.meta/generator/flatten_array_case.rb similarity index 100% rename from exercises/flatten-array/.meta/generator/flatten_array_case.rb rename to exercises/practice/flatten-array/.meta/generator/flatten_array_case.rb diff --git a/exercises/flatten-array/.meta/solutions/flatten_array.rb b/exercises/practice/flatten-array/.meta/solutions/flatten_array.rb similarity index 100% rename from exercises/flatten-array/.meta/solutions/flatten_array.rb rename to exercises/practice/flatten-array/.meta/solutions/flatten_array.rb diff --git a/exercises/flatten-array/.meta/tests.toml b/exercises/practice/flatten-array/.meta/tests.toml similarity index 100% rename from exercises/flatten-array/.meta/tests.toml rename to exercises/practice/flatten-array/.meta/tests.toml diff --git a/exercises/flatten-array/README.md b/exercises/practice/flatten-array/README.md similarity index 100% rename from exercises/flatten-array/README.md rename to exercises/practice/flatten-array/README.md diff --git a/exercises/flatten-array/flatten_array.rb b/exercises/practice/flatten-array/flatten_array.rb similarity index 100% rename from exercises/flatten-array/flatten_array.rb rename to exercises/practice/flatten-array/flatten_array.rb diff --git a/exercises/flatten-array/flatten_array_test.rb b/exercises/practice/flatten-array/flatten_array_test.rb similarity index 100% rename from exercises/flatten-array/flatten_array_test.rb rename to exercises/practice/flatten-array/flatten_array_test.rb diff --git a/exercises/food-chain/.meta/solutions/food_chain.rb b/exercises/practice/food-chain/.meta/solutions/food_chain.rb similarity index 100% rename from exercises/food-chain/.meta/solutions/food_chain.rb rename to exercises/practice/food-chain/.meta/solutions/food_chain.rb diff --git a/exercises/food-chain/.meta/tests.toml b/exercises/practice/food-chain/.meta/tests.toml similarity index 100% rename from exercises/food-chain/.meta/tests.toml rename to exercises/practice/food-chain/.meta/tests.toml diff --git a/exercises/food-chain/README.md b/exercises/practice/food-chain/README.md similarity index 100% rename from exercises/food-chain/README.md rename to exercises/practice/food-chain/README.md diff --git a/exercises/food-chain/food_chain.rb b/exercises/practice/food-chain/food_chain.rb similarity index 100% rename from exercises/food-chain/food_chain.rb rename to exercises/practice/food-chain/food_chain.rb diff --git a/exercises/food-chain/food_chain_test.rb b/exercises/practice/food-chain/food_chain_test.rb similarity index 100% rename from exercises/food-chain/food_chain_test.rb rename to exercises/practice/food-chain/food_chain_test.rb diff --git a/exercises/food-chain/song.txt b/exercises/practice/food-chain/song.txt similarity index 100% rename from exercises/food-chain/song.txt rename to exercises/practice/food-chain/song.txt diff --git a/exercises/gigasecond/.meta/generator/gigasecond_case.rb b/exercises/practice/gigasecond/.meta/generator/gigasecond_case.rb similarity index 100% rename from exercises/gigasecond/.meta/generator/gigasecond_case.rb rename to exercises/practice/gigasecond/.meta/generator/gigasecond_case.rb diff --git a/exercises/gigasecond/.meta/solutions/gigasecond.rb b/exercises/practice/gigasecond/.meta/solutions/gigasecond.rb similarity index 100% rename from exercises/gigasecond/.meta/solutions/gigasecond.rb rename to exercises/practice/gigasecond/.meta/solutions/gigasecond.rb diff --git a/exercises/gigasecond/.meta/tests.toml b/exercises/practice/gigasecond/.meta/tests.toml similarity index 100% rename from exercises/gigasecond/.meta/tests.toml rename to exercises/practice/gigasecond/.meta/tests.toml diff --git a/exercises/gigasecond/README.md b/exercises/practice/gigasecond/README.md similarity index 100% rename from exercises/gigasecond/README.md rename to exercises/practice/gigasecond/README.md diff --git a/exercises/gigasecond/gigasecond.rb b/exercises/practice/gigasecond/gigasecond.rb similarity index 100% rename from exercises/gigasecond/gigasecond.rb rename to exercises/practice/gigasecond/gigasecond.rb diff --git a/exercises/gigasecond/gigasecond_test.rb b/exercises/practice/gigasecond/gigasecond_test.rb similarity index 100% rename from exercises/gigasecond/gigasecond_test.rb rename to exercises/practice/gigasecond/gigasecond_test.rb diff --git a/exercises/grade-school/.meta/solutions/grade_school.rb b/exercises/practice/grade-school/.meta/solutions/grade_school.rb similarity index 100% rename from exercises/grade-school/.meta/solutions/grade_school.rb rename to exercises/practice/grade-school/.meta/solutions/grade_school.rb diff --git a/exercises/grade-school/.meta/tests.toml b/exercises/practice/grade-school/.meta/tests.toml similarity index 100% rename from exercises/grade-school/.meta/tests.toml rename to exercises/practice/grade-school/.meta/tests.toml diff --git a/exercises/grade-school/README.md b/exercises/practice/grade-school/README.md similarity index 100% rename from exercises/grade-school/README.md rename to exercises/practice/grade-school/README.md diff --git a/exercises/grade-school/grade_school.rb b/exercises/practice/grade-school/grade_school.rb similarity index 100% rename from exercises/grade-school/grade_school.rb rename to exercises/practice/grade-school/grade_school.rb diff --git a/exercises/grade-school/grade_school_test.rb b/exercises/practice/grade-school/grade_school_test.rb similarity index 100% rename from exercises/grade-school/grade_school_test.rb rename to exercises/practice/grade-school/grade_school_test.rb diff --git a/exercises/grains/.meta/generator/grains_case.rb b/exercises/practice/grains/.meta/generator/grains_case.rb similarity index 100% rename from exercises/grains/.meta/generator/grains_case.rb rename to exercises/practice/grains/.meta/generator/grains_case.rb diff --git a/exercises/grains/.meta/solutions/grains.rb b/exercises/practice/grains/.meta/solutions/grains.rb similarity index 100% rename from exercises/grains/.meta/solutions/grains.rb rename to exercises/practice/grains/.meta/solutions/grains.rb diff --git a/exercises/grains/README.md b/exercises/practice/grains/README.md similarity index 100% rename from exercises/grains/README.md rename to exercises/practice/grains/README.md diff --git a/exercises/grains/grains.rb b/exercises/practice/grains/grains.rb similarity index 100% rename from exercises/grains/grains.rb rename to exercises/practice/grains/grains.rb diff --git a/exercises/grains/grains_test.rb b/exercises/practice/grains/grains_test.rb similarity index 100% rename from exercises/grains/grains_test.rb rename to exercises/practice/grains/grains_test.rb diff --git a/exercises/grep/.meta/generator/grep_case.rb b/exercises/practice/grep/.meta/generator/grep_case.rb similarity index 100% rename from exercises/grep/.meta/generator/grep_case.rb rename to exercises/practice/grep/.meta/generator/grep_case.rb diff --git a/exercises/grep/.meta/generator/test_template.erb b/exercises/practice/grep/.meta/generator/test_template.erb similarity index 100% rename from exercises/grep/.meta/generator/test_template.erb rename to exercises/practice/grep/.meta/generator/test_template.erb diff --git a/exercises/grep/.meta/solutions/grep.rb b/exercises/practice/grep/.meta/solutions/grep.rb similarity index 100% rename from exercises/grep/.meta/solutions/grep.rb rename to exercises/practice/grep/.meta/solutions/grep.rb diff --git a/exercises/grep/.meta/tests.toml b/exercises/practice/grep/.meta/tests.toml similarity index 100% rename from exercises/grep/.meta/tests.toml rename to exercises/practice/grep/.meta/tests.toml diff --git a/exercises/grep/README.md b/exercises/practice/grep/README.md similarity index 100% rename from exercises/grep/README.md rename to exercises/practice/grep/README.md diff --git a/exercises/grep/grep.rb b/exercises/practice/grep/grep.rb similarity index 100% rename from exercises/grep/grep.rb rename to exercises/practice/grep/grep.rb diff --git a/exercises/grep/grep_test.rb b/exercises/practice/grep/grep_test.rb similarity index 100% rename from exercises/grep/grep_test.rb rename to exercises/practice/grep/grep_test.rb diff --git a/exercises/hamming/.meta/generator/hamming_case.rb b/exercises/practice/hamming/.meta/generator/hamming_case.rb similarity index 100% rename from exercises/hamming/.meta/generator/hamming_case.rb rename to exercises/practice/hamming/.meta/generator/hamming_case.rb diff --git a/exercises/hamming/.meta/solutions/hamming.rb b/exercises/practice/hamming/.meta/solutions/hamming.rb similarity index 100% rename from exercises/hamming/.meta/solutions/hamming.rb rename to exercises/practice/hamming/.meta/solutions/hamming.rb diff --git a/exercises/hamming/.meta/tests.toml b/exercises/practice/hamming/.meta/tests.toml similarity index 100% rename from exercises/hamming/.meta/tests.toml rename to exercises/practice/hamming/.meta/tests.toml diff --git a/exercises/hamming/README.md b/exercises/practice/hamming/README.md similarity index 100% rename from exercises/hamming/README.md rename to exercises/practice/hamming/README.md diff --git a/exercises/hamming/RUNNING_TESTS.md b/exercises/practice/hamming/RUNNING_TESTS.md similarity index 100% rename from exercises/hamming/RUNNING_TESTS.md rename to exercises/practice/hamming/RUNNING_TESTS.md diff --git a/exercises/hamming/hamming.rb b/exercises/practice/hamming/hamming.rb similarity index 100% rename from exercises/hamming/hamming.rb rename to exercises/practice/hamming/hamming.rb diff --git a/exercises/hamming/hamming_test.rb b/exercises/practice/hamming/hamming_test.rb similarity index 100% rename from exercises/hamming/hamming_test.rb rename to exercises/practice/hamming/hamming_test.rb diff --git a/exercises/hello-world/.meta/generator/hello_world_case.rb b/exercises/practice/hello-world/.meta/generator/hello_world_case.rb similarity index 100% rename from exercises/hello-world/.meta/generator/hello_world_case.rb rename to exercises/practice/hello-world/.meta/generator/hello_world_case.rb diff --git a/exercises/hello-world/.meta/generator/test_template.erb b/exercises/practice/hello-world/.meta/generator/test_template.erb similarity index 100% rename from exercises/hello-world/.meta/generator/test_template.erb rename to exercises/practice/hello-world/.meta/generator/test_template.erb diff --git a/exercises/hello-world/.meta/solutions/hello_world.rb b/exercises/practice/hello-world/.meta/solutions/hello_world.rb similarity index 100% rename from exercises/hello-world/.meta/solutions/hello_world.rb rename to exercises/practice/hello-world/.meta/solutions/hello_world.rb diff --git a/exercises/hello-world/.meta/tests.toml b/exercises/practice/hello-world/.meta/tests.toml similarity index 100% rename from exercises/hello-world/.meta/tests.toml rename to exercises/practice/hello-world/.meta/tests.toml diff --git a/exercises/hello-world/GETTING_STARTED.md b/exercises/practice/hello-world/GETTING_STARTED.md similarity index 100% rename from exercises/hello-world/GETTING_STARTED.md rename to exercises/practice/hello-world/GETTING_STARTED.md diff --git a/exercises/hello-world/README.md b/exercises/practice/hello-world/README.md similarity index 100% rename from exercises/hello-world/README.md rename to exercises/practice/hello-world/README.md diff --git a/exercises/hello-world/hello_world.rb b/exercises/practice/hello-world/hello_world.rb similarity index 100% rename from exercises/hello-world/hello_world.rb rename to exercises/practice/hello-world/hello_world.rb diff --git a/exercises/hello-world/hello_world_test.rb b/exercises/practice/hello-world/hello_world_test.rb similarity index 100% rename from exercises/hello-world/hello_world_test.rb rename to exercises/practice/hello-world/hello_world_test.rb diff --git a/exercises/hexadecimal/.meta/solutions/hexadecimal.rb b/exercises/practice/hexadecimal/.meta/solutions/hexadecimal.rb similarity index 100% rename from exercises/hexadecimal/.meta/solutions/hexadecimal.rb rename to exercises/practice/hexadecimal/.meta/solutions/hexadecimal.rb diff --git a/exercises/hexadecimal/README.md b/exercises/practice/hexadecimal/README.md similarity index 100% rename from exercises/hexadecimal/README.md rename to exercises/practice/hexadecimal/README.md diff --git a/exercises/hexadecimal/hexadecimal.rb b/exercises/practice/hexadecimal/hexadecimal.rb similarity index 100% rename from exercises/hexadecimal/hexadecimal.rb rename to exercises/practice/hexadecimal/hexadecimal.rb diff --git a/exercises/hexadecimal/hexadecimal_test.rb b/exercises/practice/hexadecimal/hexadecimal_test.rb similarity index 100% rename from exercises/hexadecimal/hexadecimal_test.rb rename to exercises/practice/hexadecimal/hexadecimal_test.rb diff --git a/exercises/high-scores/.meta/generator/high_scores_case.rb b/exercises/practice/high-scores/.meta/generator/high_scores_case.rb similarity index 100% rename from exercises/high-scores/.meta/generator/high_scores_case.rb rename to exercises/practice/high-scores/.meta/generator/high_scores_case.rb diff --git a/exercises/high-scores/.meta/hints.md b/exercises/practice/high-scores/.meta/hints.md similarity index 100% rename from exercises/high-scores/.meta/hints.md rename to exercises/practice/high-scores/.meta/hints.md diff --git a/exercises/high-scores/.meta/solutions/high_scores.rb b/exercises/practice/high-scores/.meta/solutions/high_scores.rb similarity index 100% rename from exercises/high-scores/.meta/solutions/high_scores.rb rename to exercises/practice/high-scores/.meta/solutions/high_scores.rb diff --git a/exercises/high-scores/.meta/tests.toml b/exercises/practice/high-scores/.meta/tests.toml similarity index 100% rename from exercises/high-scores/.meta/tests.toml rename to exercises/practice/high-scores/.meta/tests.toml diff --git a/exercises/high-scores/README.md b/exercises/practice/high-scores/README.md similarity index 100% rename from exercises/high-scores/README.md rename to exercises/practice/high-scores/README.md diff --git a/exercises/high-scores/high_scores.rb b/exercises/practice/high-scores/high_scores.rb similarity index 100% rename from exercises/high-scores/high_scores.rb rename to exercises/practice/high-scores/high_scores.rb diff --git a/exercises/high-scores/high_scores_test.rb b/exercises/practice/high-scores/high_scores_test.rb similarity index 100% rename from exercises/high-scores/high_scores_test.rb rename to exercises/practice/high-scores/high_scores_test.rb diff --git a/exercises/house/.meta/solutions/house.rb b/exercises/practice/house/.meta/solutions/house.rb similarity index 100% rename from exercises/house/.meta/solutions/house.rb rename to exercises/practice/house/.meta/solutions/house.rb diff --git a/exercises/house/.meta/tests.toml b/exercises/practice/house/.meta/tests.toml similarity index 100% rename from exercises/house/.meta/tests.toml rename to exercises/practice/house/.meta/tests.toml diff --git a/exercises/house/README.md b/exercises/practice/house/README.md similarity index 100% rename from exercises/house/README.md rename to exercises/practice/house/README.md diff --git a/exercises/house/house.rb b/exercises/practice/house/house.rb similarity index 100% rename from exercises/house/house.rb rename to exercises/practice/house/house.rb diff --git a/exercises/house/house_test.rb b/exercises/practice/house/house_test.rb similarity index 100% rename from exercises/house/house_test.rb rename to exercises/practice/house/house_test.rb diff --git a/exercises/isbn-verifier/.meta/generator/isbn_verifier_case.rb b/exercises/practice/isbn-verifier/.meta/generator/isbn_verifier_case.rb similarity index 100% rename from exercises/isbn-verifier/.meta/generator/isbn_verifier_case.rb rename to exercises/practice/isbn-verifier/.meta/generator/isbn_verifier_case.rb diff --git a/exercises/isbn-verifier/.meta/solutions/isbn_verifier.rb b/exercises/practice/isbn-verifier/.meta/solutions/isbn_verifier.rb similarity index 100% rename from exercises/isbn-verifier/.meta/solutions/isbn_verifier.rb rename to exercises/practice/isbn-verifier/.meta/solutions/isbn_verifier.rb diff --git a/exercises/isbn-verifier/.meta/tests.toml b/exercises/practice/isbn-verifier/.meta/tests.toml similarity index 100% rename from exercises/isbn-verifier/.meta/tests.toml rename to exercises/practice/isbn-verifier/.meta/tests.toml diff --git a/exercises/isbn-verifier/README.md b/exercises/practice/isbn-verifier/README.md similarity index 100% rename from exercises/isbn-verifier/README.md rename to exercises/practice/isbn-verifier/README.md diff --git a/exercises/isbn-verifier/isbn_verifier.rb b/exercises/practice/isbn-verifier/isbn_verifier.rb similarity index 100% rename from exercises/isbn-verifier/isbn_verifier.rb rename to exercises/practice/isbn-verifier/isbn_verifier.rb diff --git a/exercises/isbn-verifier/isbn_verifier_test.rb b/exercises/practice/isbn-verifier/isbn_verifier_test.rb similarity index 100% rename from exercises/isbn-verifier/isbn_verifier_test.rb rename to exercises/practice/isbn-verifier/isbn_verifier_test.rb diff --git a/exercises/isogram/.meta/generator/isogram_case.rb b/exercises/practice/isogram/.meta/generator/isogram_case.rb similarity index 100% rename from exercises/isogram/.meta/generator/isogram_case.rb rename to exercises/practice/isogram/.meta/generator/isogram_case.rb diff --git a/exercises/isogram/.meta/solutions/isogram.rb b/exercises/practice/isogram/.meta/solutions/isogram.rb similarity index 100% rename from exercises/isogram/.meta/solutions/isogram.rb rename to exercises/practice/isogram/.meta/solutions/isogram.rb diff --git a/exercises/isogram/.meta/tests.toml b/exercises/practice/isogram/.meta/tests.toml similarity index 100% rename from exercises/isogram/.meta/tests.toml rename to exercises/practice/isogram/.meta/tests.toml diff --git a/exercises/isogram/README.md b/exercises/practice/isogram/README.md similarity index 100% rename from exercises/isogram/README.md rename to exercises/practice/isogram/README.md diff --git a/exercises/isogram/isogram.rb b/exercises/practice/isogram/isogram.rb similarity index 100% rename from exercises/isogram/isogram.rb rename to exercises/practice/isogram/isogram.rb diff --git a/exercises/isogram/isogram_test.rb b/exercises/practice/isogram/isogram_test.rb similarity index 100% rename from exercises/isogram/isogram_test.rb rename to exercises/practice/isogram/isogram_test.rb diff --git a/exercises/kindergarten-garden/.meta/solutions/kindergarten_garden.rb b/exercises/practice/kindergarten-garden/.meta/solutions/kindergarten_garden.rb similarity index 100% rename from exercises/kindergarten-garden/.meta/solutions/kindergarten_garden.rb rename to exercises/practice/kindergarten-garden/.meta/solutions/kindergarten_garden.rb diff --git a/exercises/kindergarten-garden/.meta/tests.toml b/exercises/practice/kindergarten-garden/.meta/tests.toml similarity index 100% rename from exercises/kindergarten-garden/.meta/tests.toml rename to exercises/practice/kindergarten-garden/.meta/tests.toml diff --git a/exercises/kindergarten-garden/README.md b/exercises/practice/kindergarten-garden/README.md similarity index 100% rename from exercises/kindergarten-garden/README.md rename to exercises/practice/kindergarten-garden/README.md diff --git a/exercises/kindergarten-garden/kindergarten_garden.rb b/exercises/practice/kindergarten-garden/kindergarten_garden.rb similarity index 100% rename from exercises/kindergarten-garden/kindergarten_garden.rb rename to exercises/practice/kindergarten-garden/kindergarten_garden.rb diff --git a/exercises/kindergarten-garden/kindergarten_garden_test.rb b/exercises/practice/kindergarten-garden/kindergarten_garden_test.rb similarity index 100% rename from exercises/kindergarten-garden/kindergarten_garden_test.rb rename to exercises/practice/kindergarten-garden/kindergarten_garden_test.rb diff --git a/exercises/largest-series-product/.meta/generator/largest_series_product_case.rb b/exercises/practice/largest-series-product/.meta/generator/largest_series_product_case.rb similarity index 100% rename from exercises/largest-series-product/.meta/generator/largest_series_product_case.rb rename to exercises/practice/largest-series-product/.meta/generator/largest_series_product_case.rb diff --git a/exercises/largest-series-product/.meta/solutions/largest_series_product.rb b/exercises/practice/largest-series-product/.meta/solutions/largest_series_product.rb similarity index 100% rename from exercises/largest-series-product/.meta/solutions/largest_series_product.rb rename to exercises/practice/largest-series-product/.meta/solutions/largest_series_product.rb diff --git a/exercises/largest-series-product/.meta/tests.toml b/exercises/practice/largest-series-product/.meta/tests.toml similarity index 100% rename from exercises/largest-series-product/.meta/tests.toml rename to exercises/practice/largest-series-product/.meta/tests.toml diff --git a/exercises/largest-series-product/README.md b/exercises/practice/largest-series-product/README.md similarity index 100% rename from exercises/largest-series-product/README.md rename to exercises/practice/largest-series-product/README.md diff --git a/exercises/largest-series-product/largest_series_product.rb b/exercises/practice/largest-series-product/largest_series_product.rb similarity index 100% rename from exercises/largest-series-product/largest_series_product.rb rename to exercises/practice/largest-series-product/largest_series_product.rb diff --git a/exercises/largest-series-product/largest_series_product_test.rb b/exercises/practice/largest-series-product/largest_series_product_test.rb similarity index 100% rename from exercises/largest-series-product/largest_series_product_test.rb rename to exercises/practice/largest-series-product/largest_series_product_test.rb diff --git a/exercises/leap/.meta/generator/leap_case.rb b/exercises/practice/leap/.meta/generator/leap_case.rb similarity index 100% rename from exercises/leap/.meta/generator/leap_case.rb rename to exercises/practice/leap/.meta/generator/leap_case.rb diff --git a/exercises/leap/.meta/generator/test_template.erb b/exercises/practice/leap/.meta/generator/test_template.erb similarity index 100% rename from exercises/leap/.meta/generator/test_template.erb rename to exercises/practice/leap/.meta/generator/test_template.erb diff --git a/exercises/leap/.meta/solutions/leap.rb b/exercises/practice/leap/.meta/solutions/leap.rb similarity index 100% rename from exercises/leap/.meta/solutions/leap.rb rename to exercises/practice/leap/.meta/solutions/leap.rb diff --git a/exercises/leap/.meta/tests.toml b/exercises/practice/leap/.meta/tests.toml similarity index 100% rename from exercises/leap/.meta/tests.toml rename to exercises/practice/leap/.meta/tests.toml diff --git a/exercises/leap/README.md b/exercises/practice/leap/README.md similarity index 100% rename from exercises/leap/README.md rename to exercises/practice/leap/README.md diff --git a/exercises/leap/leap.rb b/exercises/practice/leap/leap.rb similarity index 100% rename from exercises/leap/leap.rb rename to exercises/practice/leap/leap.rb diff --git a/exercises/leap/leap_test.rb b/exercises/practice/leap/leap_test.rb similarity index 100% rename from exercises/leap/leap_test.rb rename to exercises/practice/leap/leap_test.rb diff --git a/exercises/linked-list/.meta/solutions/linked_list.rb b/exercises/practice/linked-list/.meta/solutions/linked_list.rb similarity index 100% rename from exercises/linked-list/.meta/solutions/linked_list.rb rename to exercises/practice/linked-list/.meta/solutions/linked_list.rb diff --git a/exercises/linked-list/README.md b/exercises/practice/linked-list/README.md similarity index 100% rename from exercises/linked-list/README.md rename to exercises/practice/linked-list/README.md diff --git a/exercises/linked-list/linked_list.rb b/exercises/practice/linked-list/linked_list.rb similarity index 100% rename from exercises/linked-list/linked_list.rb rename to exercises/practice/linked-list/linked_list.rb diff --git a/exercises/linked-list/linked_list_test.rb b/exercises/practice/linked-list/linked_list_test.rb similarity index 100% rename from exercises/linked-list/linked_list_test.rb rename to exercises/practice/linked-list/linked_list_test.rb diff --git a/exercises/list-ops/.meta/solutions/list_ops.rb b/exercises/practice/list-ops/.meta/solutions/list_ops.rb similarity index 100% rename from exercises/list-ops/.meta/solutions/list_ops.rb rename to exercises/practice/list-ops/.meta/solutions/list_ops.rb diff --git a/exercises/list-ops/.meta/tests.toml b/exercises/practice/list-ops/.meta/tests.toml similarity index 100% rename from exercises/list-ops/.meta/tests.toml rename to exercises/practice/list-ops/.meta/tests.toml diff --git a/exercises/list-ops/README.md b/exercises/practice/list-ops/README.md similarity index 100% rename from exercises/list-ops/README.md rename to exercises/practice/list-ops/README.md diff --git a/exercises/list-ops/list_ops.rb b/exercises/practice/list-ops/list_ops.rb similarity index 100% rename from exercises/list-ops/list_ops.rb rename to exercises/practice/list-ops/list_ops.rb diff --git a/exercises/list-ops/list_ops_test.rb b/exercises/practice/list-ops/list_ops_test.rb similarity index 100% rename from exercises/list-ops/list_ops_test.rb rename to exercises/practice/list-ops/list_ops_test.rb diff --git a/exercises/luhn/.meta/generator/luhn_case.rb b/exercises/practice/luhn/.meta/generator/luhn_case.rb similarity index 100% rename from exercises/luhn/.meta/generator/luhn_case.rb rename to exercises/practice/luhn/.meta/generator/luhn_case.rb diff --git a/exercises/luhn/.meta/solutions/luhn.rb b/exercises/practice/luhn/.meta/solutions/luhn.rb similarity index 100% rename from exercises/luhn/.meta/solutions/luhn.rb rename to exercises/practice/luhn/.meta/solutions/luhn.rb diff --git a/exercises/luhn/.meta/tests.toml b/exercises/practice/luhn/.meta/tests.toml similarity index 100% rename from exercises/luhn/.meta/tests.toml rename to exercises/practice/luhn/.meta/tests.toml diff --git a/exercises/luhn/README.md b/exercises/practice/luhn/README.md similarity index 100% rename from exercises/luhn/README.md rename to exercises/practice/luhn/README.md diff --git a/exercises/luhn/luhn.rb b/exercises/practice/luhn/luhn.rb similarity index 100% rename from exercises/luhn/luhn.rb rename to exercises/practice/luhn/luhn.rb diff --git a/exercises/luhn/luhn_test.rb b/exercises/practice/luhn/luhn_test.rb similarity index 100% rename from exercises/luhn/luhn_test.rb rename to exercises/practice/luhn/luhn_test.rb diff --git a/exercises/matching-brackets/.meta/generator/matching_brackets_case.rb b/exercises/practice/matching-brackets/.meta/generator/matching_brackets_case.rb similarity index 100% rename from exercises/matching-brackets/.meta/generator/matching_brackets_case.rb rename to exercises/practice/matching-brackets/.meta/generator/matching_brackets_case.rb diff --git a/exercises/matching-brackets/.meta/solutions/matching_brackets.rb b/exercises/practice/matching-brackets/.meta/solutions/matching_brackets.rb similarity index 100% rename from exercises/matching-brackets/.meta/solutions/matching_brackets.rb rename to exercises/practice/matching-brackets/.meta/solutions/matching_brackets.rb diff --git a/exercises/matching-brackets/.meta/tests.toml b/exercises/practice/matching-brackets/.meta/tests.toml similarity index 100% rename from exercises/matching-brackets/.meta/tests.toml rename to exercises/practice/matching-brackets/.meta/tests.toml diff --git a/exercises/matching-brackets/README.md b/exercises/practice/matching-brackets/README.md similarity index 100% rename from exercises/matching-brackets/README.md rename to exercises/practice/matching-brackets/README.md diff --git a/exercises/matching-brackets/matching_brackets.rb b/exercises/practice/matching-brackets/matching_brackets.rb similarity index 100% rename from exercises/matching-brackets/matching_brackets.rb rename to exercises/practice/matching-brackets/matching_brackets.rb diff --git a/exercises/matching-brackets/matching_brackets_test.rb b/exercises/practice/matching-brackets/matching_brackets_test.rb similarity index 100% rename from exercises/matching-brackets/matching_brackets_test.rb rename to exercises/practice/matching-brackets/matching_brackets_test.rb diff --git a/exercises/matrix/.meta/solutions/matrix.rb b/exercises/practice/matrix/.meta/solutions/matrix.rb similarity index 100% rename from exercises/matrix/.meta/solutions/matrix.rb rename to exercises/practice/matrix/.meta/solutions/matrix.rb diff --git a/exercises/matrix/.meta/tests.toml b/exercises/practice/matrix/.meta/tests.toml similarity index 100% rename from exercises/matrix/.meta/tests.toml rename to exercises/practice/matrix/.meta/tests.toml diff --git a/exercises/matrix/README.md b/exercises/practice/matrix/README.md similarity index 100% rename from exercises/matrix/README.md rename to exercises/practice/matrix/README.md diff --git a/exercises/matrix/matrix.rb b/exercises/practice/matrix/matrix.rb similarity index 100% rename from exercises/matrix/matrix.rb rename to exercises/practice/matrix/matrix.rb diff --git a/exercises/matrix/matrix_test.rb b/exercises/practice/matrix/matrix_test.rb similarity index 100% rename from exercises/matrix/matrix_test.rb rename to exercises/practice/matrix/matrix_test.rb diff --git a/exercises/meetup/.meta/generator/meetup_case.rb b/exercises/practice/meetup/.meta/generator/meetup_case.rb similarity index 100% rename from exercises/meetup/.meta/generator/meetup_case.rb rename to exercises/practice/meetup/.meta/generator/meetup_case.rb diff --git a/exercises/meetup/.meta/solutions/meetup.rb b/exercises/practice/meetup/.meta/solutions/meetup.rb similarity index 100% rename from exercises/meetup/.meta/solutions/meetup.rb rename to exercises/practice/meetup/.meta/solutions/meetup.rb diff --git a/exercises/meetup/.meta/tests.toml b/exercises/practice/meetup/.meta/tests.toml similarity index 100% rename from exercises/meetup/.meta/tests.toml rename to exercises/practice/meetup/.meta/tests.toml diff --git a/exercises/meetup/README.md b/exercises/practice/meetup/README.md similarity index 100% rename from exercises/meetup/README.md rename to exercises/practice/meetup/README.md diff --git a/exercises/meetup/meetup.rb b/exercises/practice/meetup/meetup.rb similarity index 100% rename from exercises/meetup/meetup.rb rename to exercises/practice/meetup/meetup.rb diff --git a/exercises/meetup/meetup_test.rb b/exercises/practice/meetup/meetup_test.rb similarity index 100% rename from exercises/meetup/meetup_test.rb rename to exercises/practice/meetup/meetup_test.rb diff --git a/exercises/microwave/.meta/solutions/microwave.rb b/exercises/practice/microwave/.meta/solutions/microwave.rb similarity index 100% rename from exercises/microwave/.meta/solutions/microwave.rb rename to exercises/practice/microwave/.meta/solutions/microwave.rb diff --git a/exercises/microwave/README.md b/exercises/practice/microwave/README.md similarity index 100% rename from exercises/microwave/README.md rename to exercises/practice/microwave/README.md diff --git a/exercises/microwave/microwave.rb b/exercises/practice/microwave/microwave.rb similarity index 100% rename from exercises/microwave/microwave.rb rename to exercises/practice/microwave/microwave.rb diff --git a/exercises/microwave/microwave_test.rb b/exercises/practice/microwave/microwave_test.rb similarity index 100% rename from exercises/microwave/microwave_test.rb rename to exercises/practice/microwave/microwave_test.rb diff --git a/exercises/minesweeper/.meta/solutions/minesweeper.rb b/exercises/practice/minesweeper/.meta/solutions/minesweeper.rb similarity index 100% rename from exercises/minesweeper/.meta/solutions/minesweeper.rb rename to exercises/practice/minesweeper/.meta/solutions/minesweeper.rb diff --git a/exercises/minesweeper/.meta/tests.toml b/exercises/practice/minesweeper/.meta/tests.toml similarity index 100% rename from exercises/minesweeper/.meta/tests.toml rename to exercises/practice/minesweeper/.meta/tests.toml diff --git a/exercises/minesweeper/README.md b/exercises/practice/minesweeper/README.md similarity index 100% rename from exercises/minesweeper/README.md rename to exercises/practice/minesweeper/README.md diff --git a/exercises/minesweeper/minesweeper.rb b/exercises/practice/minesweeper/minesweeper.rb similarity index 100% rename from exercises/minesweeper/minesweeper.rb rename to exercises/practice/minesweeper/minesweeper.rb diff --git a/exercises/minesweeper/minesweeper_test.rb b/exercises/practice/minesweeper/minesweeper_test.rb similarity index 100% rename from exercises/minesweeper/minesweeper_test.rb rename to exercises/practice/minesweeper/minesweeper_test.rb diff --git a/exercises/nth-prime/.meta/generator/nth_prime_case.rb b/exercises/practice/nth-prime/.meta/generator/nth_prime_case.rb similarity index 100% rename from exercises/nth-prime/.meta/generator/nth_prime_case.rb rename to exercises/practice/nth-prime/.meta/generator/nth_prime_case.rb diff --git a/exercises/nth-prime/.meta/solutions/nth_prime.rb b/exercises/practice/nth-prime/.meta/solutions/nth_prime.rb similarity index 100% rename from exercises/nth-prime/.meta/solutions/nth_prime.rb rename to exercises/practice/nth-prime/.meta/solutions/nth_prime.rb diff --git a/exercises/nth-prime/.meta/tests.toml b/exercises/practice/nth-prime/.meta/tests.toml similarity index 100% rename from exercises/nth-prime/.meta/tests.toml rename to exercises/practice/nth-prime/.meta/tests.toml diff --git a/exercises/nth-prime/README.md b/exercises/practice/nth-prime/README.md similarity index 100% rename from exercises/nth-prime/README.md rename to exercises/practice/nth-prime/README.md diff --git a/exercises/nth-prime/nth_prime.rb b/exercises/practice/nth-prime/nth_prime.rb similarity index 100% rename from exercises/nth-prime/nth_prime.rb rename to exercises/practice/nth-prime/nth_prime.rb diff --git a/exercises/nth-prime/nth_prime_test.rb b/exercises/practice/nth-prime/nth_prime_test.rb similarity index 100% rename from exercises/nth-prime/nth_prime_test.rb rename to exercises/practice/nth-prime/nth_prime_test.rb diff --git a/exercises/nucleotide-count/.meta/solutions/nucleotide_count.rb b/exercises/practice/nucleotide-count/.meta/solutions/nucleotide_count.rb similarity index 100% rename from exercises/nucleotide-count/.meta/solutions/nucleotide_count.rb rename to exercises/practice/nucleotide-count/.meta/solutions/nucleotide_count.rb diff --git a/exercises/nucleotide-count/.meta/tests.toml b/exercises/practice/nucleotide-count/.meta/tests.toml similarity index 100% rename from exercises/nucleotide-count/.meta/tests.toml rename to exercises/practice/nucleotide-count/.meta/tests.toml diff --git a/exercises/nucleotide-count/README.md b/exercises/practice/nucleotide-count/README.md similarity index 100% rename from exercises/nucleotide-count/README.md rename to exercises/practice/nucleotide-count/README.md diff --git a/exercises/nucleotide-count/nucleotide_count.rb b/exercises/practice/nucleotide-count/nucleotide_count.rb similarity index 100% rename from exercises/nucleotide-count/nucleotide_count.rb rename to exercises/practice/nucleotide-count/nucleotide_count.rb diff --git a/exercises/nucleotide-count/nucleotide_count_test.rb b/exercises/practice/nucleotide-count/nucleotide_count_test.rb similarity index 100% rename from exercises/nucleotide-count/nucleotide_count_test.rb rename to exercises/practice/nucleotide-count/nucleotide_count_test.rb diff --git a/exercises/ocr-numbers/.meta/generator/ocr_numbers_case.rb b/exercises/practice/ocr-numbers/.meta/generator/ocr_numbers_case.rb similarity index 100% rename from exercises/ocr-numbers/.meta/generator/ocr_numbers_case.rb rename to exercises/practice/ocr-numbers/.meta/generator/ocr_numbers_case.rb diff --git a/exercises/ocr-numbers/.meta/hints.md b/exercises/practice/ocr-numbers/.meta/hints.md similarity index 100% rename from exercises/ocr-numbers/.meta/hints.md rename to exercises/practice/ocr-numbers/.meta/hints.md diff --git a/exercises/ocr-numbers/.meta/solutions/ocr_numbers.rb b/exercises/practice/ocr-numbers/.meta/solutions/ocr_numbers.rb similarity index 100% rename from exercises/ocr-numbers/.meta/solutions/ocr_numbers.rb rename to exercises/practice/ocr-numbers/.meta/solutions/ocr_numbers.rb diff --git a/exercises/ocr-numbers/.meta/tests.toml b/exercises/practice/ocr-numbers/.meta/tests.toml similarity index 100% rename from exercises/ocr-numbers/.meta/tests.toml rename to exercises/practice/ocr-numbers/.meta/tests.toml diff --git a/exercises/ocr-numbers/README.md b/exercises/practice/ocr-numbers/README.md similarity index 100% rename from exercises/ocr-numbers/README.md rename to exercises/practice/ocr-numbers/README.md diff --git a/exercises/ocr-numbers/ocr_numbers.rb b/exercises/practice/ocr-numbers/ocr_numbers.rb similarity index 100% rename from exercises/ocr-numbers/ocr_numbers.rb rename to exercises/practice/ocr-numbers/ocr_numbers.rb diff --git a/exercises/ocr-numbers/ocr_numbers_test.rb b/exercises/practice/ocr-numbers/ocr_numbers_test.rb similarity index 100% rename from exercises/ocr-numbers/ocr_numbers_test.rb rename to exercises/practice/ocr-numbers/ocr_numbers_test.rb diff --git a/exercises/octal/.meta/solutions/octal.rb b/exercises/practice/octal/.meta/solutions/octal.rb similarity index 100% rename from exercises/octal/.meta/solutions/octal.rb rename to exercises/practice/octal/.meta/solutions/octal.rb diff --git a/exercises/octal/README.md b/exercises/practice/octal/README.md similarity index 100% rename from exercises/octal/README.md rename to exercises/practice/octal/README.md diff --git a/exercises/octal/octal.rb b/exercises/practice/octal/octal.rb similarity index 100% rename from exercises/octal/octal.rb rename to exercises/practice/octal/octal.rb diff --git a/exercises/octal/octal_test.rb b/exercises/practice/octal/octal_test.rb similarity index 100% rename from exercises/octal/octal_test.rb rename to exercises/practice/octal/octal_test.rb diff --git a/exercises/palindrome-products/.meta/solutions/palindrome_products.rb b/exercises/practice/palindrome-products/.meta/solutions/palindrome_products.rb similarity index 100% rename from exercises/palindrome-products/.meta/solutions/palindrome_products.rb rename to exercises/practice/palindrome-products/.meta/solutions/palindrome_products.rb diff --git a/exercises/palindrome-products/.meta/tests.toml b/exercises/practice/palindrome-products/.meta/tests.toml similarity index 100% rename from exercises/palindrome-products/.meta/tests.toml rename to exercises/practice/palindrome-products/.meta/tests.toml diff --git a/exercises/palindrome-products/README.md b/exercises/practice/palindrome-products/README.md similarity index 100% rename from exercises/palindrome-products/README.md rename to exercises/practice/palindrome-products/README.md diff --git a/exercises/palindrome-products/palindrome_products.rb b/exercises/practice/palindrome-products/palindrome_products.rb similarity index 100% rename from exercises/palindrome-products/palindrome_products.rb rename to exercises/practice/palindrome-products/palindrome_products.rb diff --git a/exercises/palindrome-products/palindrome_products_test.rb b/exercises/practice/palindrome-products/palindrome_products_test.rb similarity index 100% rename from exercises/palindrome-products/palindrome_products_test.rb rename to exercises/practice/palindrome-products/palindrome_products_test.rb diff --git a/exercises/pangram/.meta/generator/pangram_case.rb b/exercises/practice/pangram/.meta/generator/pangram_case.rb similarity index 100% rename from exercises/pangram/.meta/generator/pangram_case.rb rename to exercises/practice/pangram/.meta/generator/pangram_case.rb diff --git a/exercises/pangram/.meta/solutions/pangram.rb b/exercises/practice/pangram/.meta/solutions/pangram.rb similarity index 100% rename from exercises/pangram/.meta/solutions/pangram.rb rename to exercises/practice/pangram/.meta/solutions/pangram.rb diff --git a/exercises/pangram/.meta/tests.toml b/exercises/practice/pangram/.meta/tests.toml similarity index 100% rename from exercises/pangram/.meta/tests.toml rename to exercises/practice/pangram/.meta/tests.toml diff --git a/exercises/pangram/README.md b/exercises/practice/pangram/README.md similarity index 100% rename from exercises/pangram/README.md rename to exercises/practice/pangram/README.md diff --git a/exercises/pangram/pangram.rb b/exercises/practice/pangram/pangram.rb similarity index 100% rename from exercises/pangram/pangram.rb rename to exercises/practice/pangram/pangram.rb diff --git a/exercises/pangram/pangram_test.rb b/exercises/practice/pangram/pangram_test.rb similarity index 100% rename from exercises/pangram/pangram_test.rb rename to exercises/practice/pangram/pangram_test.rb diff --git a/exercises/pascals-triangle/.meta/solutions/pascals_triangle.rb b/exercises/practice/pascals-triangle/.meta/solutions/pascals_triangle.rb similarity index 100% rename from exercises/pascals-triangle/.meta/solutions/pascals_triangle.rb rename to exercises/practice/pascals-triangle/.meta/solutions/pascals_triangle.rb diff --git a/exercises/pascals-triangle/.meta/tests.toml b/exercises/practice/pascals-triangle/.meta/tests.toml similarity index 100% rename from exercises/pascals-triangle/.meta/tests.toml rename to exercises/practice/pascals-triangle/.meta/tests.toml diff --git a/exercises/pascals-triangle/README.md b/exercises/practice/pascals-triangle/README.md similarity index 100% rename from exercises/pascals-triangle/README.md rename to exercises/practice/pascals-triangle/README.md diff --git a/exercises/pascals-triangle/pascals_triangle.rb b/exercises/practice/pascals-triangle/pascals_triangle.rb similarity index 100% rename from exercises/pascals-triangle/pascals_triangle.rb rename to exercises/practice/pascals-triangle/pascals_triangle.rb diff --git a/exercises/pascals-triangle/pascals_triangle_test.rb b/exercises/practice/pascals-triangle/pascals_triangle_test.rb similarity index 100% rename from exercises/pascals-triangle/pascals_triangle_test.rb rename to exercises/practice/pascals-triangle/pascals_triangle_test.rb diff --git a/exercises/perfect-numbers/.meta/solutions/perfect_numbers.rb b/exercises/practice/perfect-numbers/.meta/solutions/perfect_numbers.rb old mode 100755 new mode 100644 similarity index 100% rename from exercises/perfect-numbers/.meta/solutions/perfect_numbers.rb rename to exercises/practice/perfect-numbers/.meta/solutions/perfect_numbers.rb diff --git a/exercises/perfect-numbers/.meta/tests.toml b/exercises/practice/perfect-numbers/.meta/tests.toml similarity index 100% rename from exercises/perfect-numbers/.meta/tests.toml rename to exercises/practice/perfect-numbers/.meta/tests.toml diff --git a/exercises/perfect-numbers/README.md b/exercises/practice/perfect-numbers/README.md similarity index 100% rename from exercises/perfect-numbers/README.md rename to exercises/practice/perfect-numbers/README.md diff --git a/exercises/perfect-numbers/perfect_numbers.rb b/exercises/practice/perfect-numbers/perfect_numbers.rb similarity index 100% rename from exercises/perfect-numbers/perfect_numbers.rb rename to exercises/practice/perfect-numbers/perfect_numbers.rb diff --git a/exercises/perfect-numbers/perfect_numbers_test.rb b/exercises/practice/perfect-numbers/perfect_numbers_test.rb similarity index 100% rename from exercises/perfect-numbers/perfect_numbers_test.rb rename to exercises/practice/perfect-numbers/perfect_numbers_test.rb diff --git a/exercises/phone-number/.meta/generator/phone_number_case.rb b/exercises/practice/phone-number/.meta/generator/phone_number_case.rb similarity index 100% rename from exercises/phone-number/.meta/generator/phone_number_case.rb rename to exercises/practice/phone-number/.meta/generator/phone_number_case.rb diff --git a/exercises/phone-number/.meta/solutions/phone_number.rb b/exercises/practice/phone-number/.meta/solutions/phone_number.rb similarity index 100% rename from exercises/phone-number/.meta/solutions/phone_number.rb rename to exercises/practice/phone-number/.meta/solutions/phone_number.rb diff --git a/exercises/phone-number/.meta/tests.toml b/exercises/practice/phone-number/.meta/tests.toml similarity index 100% rename from exercises/phone-number/.meta/tests.toml rename to exercises/practice/phone-number/.meta/tests.toml diff --git a/exercises/phone-number/README.md b/exercises/practice/phone-number/README.md similarity index 100% rename from exercises/phone-number/README.md rename to exercises/practice/phone-number/README.md diff --git a/exercises/phone-number/phone_number.rb b/exercises/practice/phone-number/phone_number.rb similarity index 100% rename from exercises/phone-number/phone_number.rb rename to exercises/practice/phone-number/phone_number.rb diff --git a/exercises/phone-number/phone_number_test.rb b/exercises/practice/phone-number/phone_number_test.rb similarity index 100% rename from exercises/phone-number/phone_number_test.rb rename to exercises/practice/phone-number/phone_number_test.rb diff --git a/exercises/pig-latin/.meta/generator/pig_latin_case.rb b/exercises/practice/pig-latin/.meta/generator/pig_latin_case.rb similarity index 100% rename from exercises/pig-latin/.meta/generator/pig_latin_case.rb rename to exercises/practice/pig-latin/.meta/generator/pig_latin_case.rb diff --git a/exercises/pig-latin/.meta/solutions/pig_latin.rb b/exercises/practice/pig-latin/.meta/solutions/pig_latin.rb similarity index 100% rename from exercises/pig-latin/.meta/solutions/pig_latin.rb rename to exercises/practice/pig-latin/.meta/solutions/pig_latin.rb diff --git a/exercises/pig-latin/.meta/tests.toml b/exercises/practice/pig-latin/.meta/tests.toml similarity index 100% rename from exercises/pig-latin/.meta/tests.toml rename to exercises/practice/pig-latin/.meta/tests.toml diff --git a/exercises/pig-latin/README.md b/exercises/practice/pig-latin/README.md similarity index 100% rename from exercises/pig-latin/README.md rename to exercises/practice/pig-latin/README.md diff --git a/exercises/pig-latin/pig_latin.rb b/exercises/practice/pig-latin/pig_latin.rb similarity index 100% rename from exercises/pig-latin/pig_latin.rb rename to exercises/practice/pig-latin/pig_latin.rb diff --git a/exercises/pig-latin/pig_latin_test.rb b/exercises/practice/pig-latin/pig_latin_test.rb similarity index 100% rename from exercises/pig-latin/pig_latin_test.rb rename to exercises/practice/pig-latin/pig_latin_test.rb diff --git a/exercises/point-mutations/.meta/solutions/point_mutations.rb b/exercises/practice/point-mutations/.meta/solutions/point_mutations.rb similarity index 100% rename from exercises/point-mutations/.meta/solutions/point_mutations.rb rename to exercises/practice/point-mutations/.meta/solutions/point_mutations.rb diff --git a/exercises/point-mutations/README.md b/exercises/practice/point-mutations/README.md similarity index 100% rename from exercises/point-mutations/README.md rename to exercises/practice/point-mutations/README.md diff --git a/exercises/point-mutations/point_mutations.rb b/exercises/practice/point-mutations/point_mutations.rb similarity index 100% rename from exercises/point-mutations/point_mutations.rb rename to exercises/practice/point-mutations/point_mutations.rb diff --git a/exercises/point-mutations/point_mutations_test.rb b/exercises/practice/point-mutations/point_mutations_test.rb similarity index 100% rename from exercises/point-mutations/point_mutations_test.rb rename to exercises/practice/point-mutations/point_mutations_test.rb diff --git a/exercises/poker/.meta/solutions/poker.rb b/exercises/practice/poker/.meta/solutions/poker.rb similarity index 100% rename from exercises/poker/.meta/solutions/poker.rb rename to exercises/practice/poker/.meta/solutions/poker.rb diff --git a/exercises/poker/.meta/tests.toml b/exercises/practice/poker/.meta/tests.toml similarity index 100% rename from exercises/poker/.meta/tests.toml rename to exercises/practice/poker/.meta/tests.toml diff --git a/exercises/poker/README.md b/exercises/practice/poker/README.md similarity index 100% rename from exercises/poker/README.md rename to exercises/practice/poker/README.md diff --git a/exercises/poker/poker.rb b/exercises/practice/poker/poker.rb similarity index 100% rename from exercises/poker/poker.rb rename to exercises/practice/poker/poker.rb diff --git a/exercises/poker/poker_test.rb b/exercises/practice/poker/poker_test.rb similarity index 100% rename from exercises/poker/poker_test.rb rename to exercises/practice/poker/poker_test.rb diff --git a/exercises/prime-factors/.meta/solutions/prime_factors.rb b/exercises/practice/prime-factors/.meta/solutions/prime_factors.rb similarity index 100% rename from exercises/prime-factors/.meta/solutions/prime_factors.rb rename to exercises/practice/prime-factors/.meta/solutions/prime_factors.rb diff --git a/exercises/prime-factors/.meta/tests.toml b/exercises/practice/prime-factors/.meta/tests.toml similarity index 100% rename from exercises/prime-factors/.meta/tests.toml rename to exercises/practice/prime-factors/.meta/tests.toml diff --git a/exercises/prime-factors/README.md b/exercises/practice/prime-factors/README.md similarity index 100% rename from exercises/prime-factors/README.md rename to exercises/practice/prime-factors/README.md diff --git a/exercises/prime-factors/prime_factors.rb b/exercises/practice/prime-factors/prime_factors.rb similarity index 100% rename from exercises/prime-factors/prime_factors.rb rename to exercises/practice/prime-factors/prime_factors.rb diff --git a/exercises/prime-factors/prime_factors_test.rb b/exercises/practice/prime-factors/prime_factors_test.rb similarity index 100% rename from exercises/prime-factors/prime_factors_test.rb rename to exercises/practice/prime-factors/prime_factors_test.rb diff --git a/exercises/protein-translation/.meta/solutions/protein_translation.rb b/exercises/practice/protein-translation/.meta/solutions/protein_translation.rb similarity index 100% rename from exercises/protein-translation/.meta/solutions/protein_translation.rb rename to exercises/practice/protein-translation/.meta/solutions/protein_translation.rb diff --git a/exercises/protein-translation/.meta/tests.toml b/exercises/practice/protein-translation/.meta/tests.toml similarity index 100% rename from exercises/protein-translation/.meta/tests.toml rename to exercises/practice/protein-translation/.meta/tests.toml diff --git a/exercises/protein-translation/README.md b/exercises/practice/protein-translation/README.md similarity index 100% rename from exercises/protein-translation/README.md rename to exercises/practice/protein-translation/README.md diff --git a/exercises/protein-translation/protein_translation.rb b/exercises/practice/protein-translation/protein_translation.rb similarity index 100% rename from exercises/protein-translation/protein_translation.rb rename to exercises/practice/protein-translation/protein_translation.rb diff --git a/exercises/protein-translation/protein_translation_test.rb b/exercises/practice/protein-translation/protein_translation_test.rb similarity index 100% rename from exercises/protein-translation/protein_translation_test.rb rename to exercises/practice/protein-translation/protein_translation_test.rb diff --git a/exercises/proverb/.meta/solutions/proverb.rb b/exercises/practice/proverb/.meta/solutions/proverb.rb similarity index 100% rename from exercises/proverb/.meta/solutions/proverb.rb rename to exercises/practice/proverb/.meta/solutions/proverb.rb diff --git a/exercises/proverb/.meta/tests.toml b/exercises/practice/proverb/.meta/tests.toml similarity index 100% rename from exercises/proverb/.meta/tests.toml rename to exercises/practice/proverb/.meta/tests.toml diff --git a/exercises/proverb/README.md b/exercises/practice/proverb/README.md similarity index 100% rename from exercises/proverb/README.md rename to exercises/practice/proverb/README.md diff --git a/exercises/proverb/proverb.rb b/exercises/practice/proverb/proverb.rb similarity index 100% rename from exercises/proverb/proverb.rb rename to exercises/practice/proverb/proverb.rb diff --git a/exercises/proverb/proverb_test.rb b/exercises/practice/proverb/proverb_test.rb similarity index 100% rename from exercises/proverb/proverb_test.rb rename to exercises/practice/proverb/proverb_test.rb diff --git a/exercises/pythagorean-triplet/.meta/solutions/pythagorean_triplet.rb b/exercises/practice/pythagorean-triplet/.meta/solutions/pythagorean_triplet.rb similarity index 100% rename from exercises/pythagorean-triplet/.meta/solutions/pythagorean_triplet.rb rename to exercises/practice/pythagorean-triplet/.meta/solutions/pythagorean_triplet.rb diff --git a/exercises/pythagorean-triplet/.meta/tests.toml b/exercises/practice/pythagorean-triplet/.meta/tests.toml similarity index 100% rename from exercises/pythagorean-triplet/.meta/tests.toml rename to exercises/practice/pythagorean-triplet/.meta/tests.toml diff --git a/exercises/pythagorean-triplet/README.md b/exercises/practice/pythagorean-triplet/README.md similarity index 100% rename from exercises/pythagorean-triplet/README.md rename to exercises/practice/pythagorean-triplet/README.md diff --git a/exercises/pythagorean-triplet/pythagorean_triplet.rb b/exercises/practice/pythagorean-triplet/pythagorean_triplet.rb similarity index 100% rename from exercises/pythagorean-triplet/pythagorean_triplet.rb rename to exercises/practice/pythagorean-triplet/pythagorean_triplet.rb diff --git a/exercises/pythagorean-triplet/pythagorean_triplet_test.rb b/exercises/practice/pythagorean-triplet/pythagorean_triplet_test.rb similarity index 100% rename from exercises/pythagorean-triplet/pythagorean_triplet_test.rb rename to exercises/practice/pythagorean-triplet/pythagorean_triplet_test.rb diff --git a/exercises/queen-attack/.meta/generator/queen_attack_case.rb b/exercises/practice/queen-attack/.meta/generator/queen_attack_case.rb similarity index 100% rename from exercises/queen-attack/.meta/generator/queen_attack_case.rb rename to exercises/practice/queen-attack/.meta/generator/queen_attack_case.rb diff --git a/exercises/queen-attack/.meta/solutions/queen_attack.rb b/exercises/practice/queen-attack/.meta/solutions/queen_attack.rb similarity index 100% rename from exercises/queen-attack/.meta/solutions/queen_attack.rb rename to exercises/practice/queen-attack/.meta/solutions/queen_attack.rb diff --git a/exercises/queen-attack/.meta/tests.toml b/exercises/practice/queen-attack/.meta/tests.toml similarity index 100% rename from exercises/queen-attack/.meta/tests.toml rename to exercises/practice/queen-attack/.meta/tests.toml diff --git a/exercises/queen-attack/README.md b/exercises/practice/queen-attack/README.md similarity index 100% rename from exercises/queen-attack/README.md rename to exercises/practice/queen-attack/README.md diff --git a/exercises/queen-attack/queen_attack.rb b/exercises/practice/queen-attack/queen_attack.rb similarity index 100% rename from exercises/queen-attack/queen_attack.rb rename to exercises/practice/queen-attack/queen_attack.rb diff --git a/exercises/queen-attack/queen_attack_test.rb b/exercises/practice/queen-attack/queen_attack_test.rb similarity index 100% rename from exercises/queen-attack/queen_attack_test.rb rename to exercises/practice/queen-attack/queen_attack_test.rb diff --git a/exercises/rail-fence-cipher/.meta/solutions/rail_fence_cipher.rb b/exercises/practice/rail-fence-cipher/.meta/solutions/rail_fence_cipher.rb similarity index 100% rename from exercises/rail-fence-cipher/.meta/solutions/rail_fence_cipher.rb rename to exercises/practice/rail-fence-cipher/.meta/solutions/rail_fence_cipher.rb diff --git a/exercises/rail-fence-cipher/.meta/tests.toml b/exercises/practice/rail-fence-cipher/.meta/tests.toml similarity index 100% rename from exercises/rail-fence-cipher/.meta/tests.toml rename to exercises/practice/rail-fence-cipher/.meta/tests.toml diff --git a/exercises/rail-fence-cipher/README.md b/exercises/practice/rail-fence-cipher/README.md similarity index 100% rename from exercises/rail-fence-cipher/README.md rename to exercises/practice/rail-fence-cipher/README.md diff --git a/exercises/rail-fence-cipher/rail_fence_cipher.rb b/exercises/practice/rail-fence-cipher/rail_fence_cipher.rb similarity index 100% rename from exercises/rail-fence-cipher/rail_fence_cipher.rb rename to exercises/practice/rail-fence-cipher/rail_fence_cipher.rb diff --git a/exercises/rail-fence-cipher/rail_fence_cipher_test.rb b/exercises/practice/rail-fence-cipher/rail_fence_cipher_test.rb similarity index 100% rename from exercises/rail-fence-cipher/rail_fence_cipher_test.rb rename to exercises/practice/rail-fence-cipher/rail_fence_cipher_test.rb diff --git a/exercises/raindrops/.meta/generator/raindrops_case.rb b/exercises/practice/raindrops/.meta/generator/raindrops_case.rb similarity index 100% rename from exercises/raindrops/.meta/generator/raindrops_case.rb rename to exercises/practice/raindrops/.meta/generator/raindrops_case.rb diff --git a/exercises/raindrops/.meta/solutions/raindrops.rb b/exercises/practice/raindrops/.meta/solutions/raindrops.rb similarity index 100% rename from exercises/raindrops/.meta/solutions/raindrops.rb rename to exercises/practice/raindrops/.meta/solutions/raindrops.rb diff --git a/exercises/raindrops/.meta/tests.toml b/exercises/practice/raindrops/.meta/tests.toml similarity index 100% rename from exercises/raindrops/.meta/tests.toml rename to exercises/practice/raindrops/.meta/tests.toml diff --git a/exercises/raindrops/README.md b/exercises/practice/raindrops/README.md similarity index 100% rename from exercises/raindrops/README.md rename to exercises/practice/raindrops/README.md diff --git a/exercises/raindrops/raindrops.rb b/exercises/practice/raindrops/raindrops.rb similarity index 100% rename from exercises/raindrops/raindrops.rb rename to exercises/practice/raindrops/raindrops.rb diff --git a/exercises/raindrops/raindrops_test.rb b/exercises/practice/raindrops/raindrops_test.rb similarity index 100% rename from exercises/raindrops/raindrops_test.rb rename to exercises/practice/raindrops/raindrops_test.rb diff --git a/exercises/resistor-color-duo/.meta/generator/resistor_color_duo_case.rb b/exercises/practice/resistor-color-duo/.meta/generator/resistor_color_duo_case.rb similarity index 100% rename from exercises/resistor-color-duo/.meta/generator/resistor_color_duo_case.rb rename to exercises/practice/resistor-color-duo/.meta/generator/resistor_color_duo_case.rb diff --git a/exercises/resistor-color-duo/.meta/solutions/resistor_color_duo.rb b/exercises/practice/resistor-color-duo/.meta/solutions/resistor_color_duo.rb similarity index 100% rename from exercises/resistor-color-duo/.meta/solutions/resistor_color_duo.rb rename to exercises/practice/resistor-color-duo/.meta/solutions/resistor_color_duo.rb diff --git a/exercises/resistor-color-duo/.meta/tests.toml b/exercises/practice/resistor-color-duo/.meta/tests.toml similarity index 100% rename from exercises/resistor-color-duo/.meta/tests.toml rename to exercises/practice/resistor-color-duo/.meta/tests.toml diff --git a/exercises/resistor-color-duo/README.md b/exercises/practice/resistor-color-duo/README.md similarity index 100% rename from exercises/resistor-color-duo/README.md rename to exercises/practice/resistor-color-duo/README.md diff --git a/exercises/resistor-color-duo/resistor_color_duo.rb b/exercises/practice/resistor-color-duo/resistor_color_duo.rb similarity index 100% rename from exercises/resistor-color-duo/resistor_color_duo.rb rename to exercises/practice/resistor-color-duo/resistor_color_duo.rb diff --git a/exercises/resistor-color-duo/resistor_color_duo_test.rb b/exercises/practice/resistor-color-duo/resistor_color_duo_test.rb similarity index 100% rename from exercises/resistor-color-duo/resistor_color_duo_test.rb rename to exercises/practice/resistor-color-duo/resistor_color_duo_test.rb diff --git a/exercises/resistor-color-trio/.meta/generator/resistor_color_trio_case.rb b/exercises/practice/resistor-color-trio/.meta/generator/resistor_color_trio_case.rb similarity index 100% rename from exercises/resistor-color-trio/.meta/generator/resistor_color_trio_case.rb rename to exercises/practice/resistor-color-trio/.meta/generator/resistor_color_trio_case.rb diff --git a/exercises/resistor-color-trio/.meta/solutions/resistor_color_trio.rb b/exercises/practice/resistor-color-trio/.meta/solutions/resistor_color_trio.rb similarity index 100% rename from exercises/resistor-color-trio/.meta/solutions/resistor_color_trio.rb rename to exercises/practice/resistor-color-trio/.meta/solutions/resistor_color_trio.rb diff --git a/exercises/resistor-color-trio/.meta/tests.toml b/exercises/practice/resistor-color-trio/.meta/tests.toml similarity index 100% rename from exercises/resistor-color-trio/.meta/tests.toml rename to exercises/practice/resistor-color-trio/.meta/tests.toml diff --git a/exercises/resistor-color-trio/README.md b/exercises/practice/resistor-color-trio/README.md similarity index 100% rename from exercises/resistor-color-trio/README.md rename to exercises/practice/resistor-color-trio/README.md diff --git a/exercises/resistor-color-trio/resistor_color_trio.rb b/exercises/practice/resistor-color-trio/resistor_color_trio.rb similarity index 100% rename from exercises/resistor-color-trio/resistor_color_trio.rb rename to exercises/practice/resistor-color-trio/resistor_color_trio.rb diff --git a/exercises/resistor-color-trio/resistor_color_trio_test.rb b/exercises/practice/resistor-color-trio/resistor_color_trio_test.rb similarity index 100% rename from exercises/resistor-color-trio/resistor_color_trio_test.rb rename to exercises/practice/resistor-color-trio/resistor_color_trio_test.rb diff --git a/exercises/resistor-color/.meta/generator/resistor_color_case.rb b/exercises/practice/resistor-color/.meta/generator/resistor_color_case.rb similarity index 100% rename from exercises/resistor-color/.meta/generator/resistor_color_case.rb rename to exercises/practice/resistor-color/.meta/generator/resistor_color_case.rb diff --git a/exercises/resistor-color/.meta/solutions/resistor_color.rb b/exercises/practice/resistor-color/.meta/solutions/resistor_color.rb similarity index 100% rename from exercises/resistor-color/.meta/solutions/resistor_color.rb rename to exercises/practice/resistor-color/.meta/solutions/resistor_color.rb diff --git a/exercises/resistor-color/.meta/tests.toml b/exercises/practice/resistor-color/.meta/tests.toml similarity index 100% rename from exercises/resistor-color/.meta/tests.toml rename to exercises/practice/resistor-color/.meta/tests.toml diff --git a/exercises/resistor-color/README.md b/exercises/practice/resistor-color/README.md similarity index 100% rename from exercises/resistor-color/README.md rename to exercises/practice/resistor-color/README.md diff --git a/exercises/resistor-color/resistor_color.rb b/exercises/practice/resistor-color/resistor_color.rb similarity index 100% rename from exercises/resistor-color/resistor_color.rb rename to exercises/practice/resistor-color/resistor_color.rb diff --git a/exercises/resistor-color/resistor_color_test.rb b/exercises/practice/resistor-color/resistor_color_test.rb similarity index 100% rename from exercises/resistor-color/resistor_color_test.rb rename to exercises/practice/resistor-color/resistor_color_test.rb diff --git a/exercises/rna-transcription/.meta/generator/rna_transcription_case.rb b/exercises/practice/rna-transcription/.meta/generator/rna_transcription_case.rb similarity index 100% rename from exercises/rna-transcription/.meta/generator/rna_transcription_case.rb rename to exercises/practice/rna-transcription/.meta/generator/rna_transcription_case.rb diff --git a/exercises/rna-transcription/.meta/solutions/rna_transcription.rb b/exercises/practice/rna-transcription/.meta/solutions/rna_transcription.rb similarity index 100% rename from exercises/rna-transcription/.meta/solutions/rna_transcription.rb rename to exercises/practice/rna-transcription/.meta/solutions/rna_transcription.rb diff --git a/exercises/rna-transcription/.meta/tests.toml b/exercises/practice/rna-transcription/.meta/tests.toml similarity index 100% rename from exercises/rna-transcription/.meta/tests.toml rename to exercises/practice/rna-transcription/.meta/tests.toml diff --git a/exercises/rna-transcription/README.md b/exercises/practice/rna-transcription/README.md similarity index 100% rename from exercises/rna-transcription/README.md rename to exercises/practice/rna-transcription/README.md diff --git a/exercises/rna-transcription/rna_transcription.rb b/exercises/practice/rna-transcription/rna_transcription.rb similarity index 100% rename from exercises/rna-transcription/rna_transcription.rb rename to exercises/practice/rna-transcription/rna_transcription.rb diff --git a/exercises/rna-transcription/rna_transcription_test.rb b/exercises/practice/rna-transcription/rna_transcription_test.rb similarity index 100% rename from exercises/rna-transcription/rna_transcription_test.rb rename to exercises/practice/rna-transcription/rna_transcription_test.rb diff --git a/exercises/robot-name/.meta/hints.md b/exercises/practice/robot-name/.meta/hints.md similarity index 100% rename from exercises/robot-name/.meta/hints.md rename to exercises/practice/robot-name/.meta/hints.md diff --git a/exercises/robot-name/.meta/solutions/robot_name.rb b/exercises/practice/robot-name/.meta/solutions/robot_name.rb similarity index 100% rename from exercises/robot-name/.meta/solutions/robot_name.rb rename to exercises/practice/robot-name/.meta/solutions/robot_name.rb diff --git a/exercises/robot-name/README.md b/exercises/practice/robot-name/README.md similarity index 100% rename from exercises/robot-name/README.md rename to exercises/practice/robot-name/README.md diff --git a/exercises/robot-name/robot_name.rb b/exercises/practice/robot-name/robot_name.rb similarity index 100% rename from exercises/robot-name/robot_name.rb rename to exercises/practice/robot-name/robot_name.rb diff --git a/exercises/robot-name/robot_name_test.rb b/exercises/practice/robot-name/robot_name_test.rb similarity index 100% rename from exercises/robot-name/robot_name_test.rb rename to exercises/practice/robot-name/robot_name_test.rb diff --git a/exercises/robot-simulator/.meta/solutions/robot_simulator.rb b/exercises/practice/robot-simulator/.meta/solutions/robot_simulator.rb similarity index 100% rename from exercises/robot-simulator/.meta/solutions/robot_simulator.rb rename to exercises/practice/robot-simulator/.meta/solutions/robot_simulator.rb diff --git a/exercises/robot-simulator/.meta/tests.toml b/exercises/practice/robot-simulator/.meta/tests.toml similarity index 100% rename from exercises/robot-simulator/.meta/tests.toml rename to exercises/practice/robot-simulator/.meta/tests.toml diff --git a/exercises/robot-simulator/README.md b/exercises/practice/robot-simulator/README.md similarity index 100% rename from exercises/robot-simulator/README.md rename to exercises/practice/robot-simulator/README.md diff --git a/exercises/robot-simulator/robot_simulator.rb b/exercises/practice/robot-simulator/robot_simulator.rb similarity index 100% rename from exercises/robot-simulator/robot_simulator.rb rename to exercises/practice/robot-simulator/robot_simulator.rb diff --git a/exercises/robot-simulator/robot_simulator_test.rb b/exercises/practice/robot-simulator/robot_simulator_test.rb similarity index 100% rename from exercises/robot-simulator/robot_simulator_test.rb rename to exercises/practice/robot-simulator/robot_simulator_test.rb diff --git a/exercises/roman-numerals/.meta/generator/roman_numerals_case.rb b/exercises/practice/roman-numerals/.meta/generator/roman_numerals_case.rb similarity index 100% rename from exercises/roman-numerals/.meta/generator/roman_numerals_case.rb rename to exercises/practice/roman-numerals/.meta/generator/roman_numerals_case.rb diff --git a/exercises/roman-numerals/.meta/solutions/roman_numerals.rb b/exercises/practice/roman-numerals/.meta/solutions/roman_numerals.rb similarity index 100% rename from exercises/roman-numerals/.meta/solutions/roman_numerals.rb rename to exercises/practice/roman-numerals/.meta/solutions/roman_numerals.rb diff --git a/exercises/roman-numerals/.meta/tests.toml b/exercises/practice/roman-numerals/.meta/tests.toml similarity index 100% rename from exercises/roman-numerals/.meta/tests.toml rename to exercises/practice/roman-numerals/.meta/tests.toml diff --git a/exercises/roman-numerals/README.md b/exercises/practice/roman-numerals/README.md similarity index 100% rename from exercises/roman-numerals/README.md rename to exercises/practice/roman-numerals/README.md diff --git a/exercises/roman-numerals/roman_numerals.rb b/exercises/practice/roman-numerals/roman_numerals.rb similarity index 100% rename from exercises/roman-numerals/roman_numerals.rb rename to exercises/practice/roman-numerals/roman_numerals.rb diff --git a/exercises/roman-numerals/roman_numerals_test.rb b/exercises/practice/roman-numerals/roman_numerals_test.rb similarity index 100% rename from exercises/roman-numerals/roman_numerals_test.rb rename to exercises/practice/roman-numerals/roman_numerals_test.rb diff --git a/exercises/rotational-cipher/.meta/generator/rotational_cipher_case.rb b/exercises/practice/rotational-cipher/.meta/generator/rotational_cipher_case.rb similarity index 100% rename from exercises/rotational-cipher/.meta/generator/rotational_cipher_case.rb rename to exercises/practice/rotational-cipher/.meta/generator/rotational_cipher_case.rb diff --git a/exercises/rotational-cipher/.meta/solutions/rotational_cipher.rb b/exercises/practice/rotational-cipher/.meta/solutions/rotational_cipher.rb similarity index 100% rename from exercises/rotational-cipher/.meta/solutions/rotational_cipher.rb rename to exercises/practice/rotational-cipher/.meta/solutions/rotational_cipher.rb diff --git a/exercises/rotational-cipher/.meta/tests.toml b/exercises/practice/rotational-cipher/.meta/tests.toml similarity index 100% rename from exercises/rotational-cipher/.meta/tests.toml rename to exercises/practice/rotational-cipher/.meta/tests.toml diff --git a/exercises/rotational-cipher/README.md b/exercises/practice/rotational-cipher/README.md similarity index 100% rename from exercises/rotational-cipher/README.md rename to exercises/practice/rotational-cipher/README.md diff --git a/exercises/rotational-cipher/rotational_cipher.rb b/exercises/practice/rotational-cipher/rotational_cipher.rb similarity index 100% rename from exercises/rotational-cipher/rotational_cipher.rb rename to exercises/practice/rotational-cipher/rotational_cipher.rb diff --git a/exercises/rotational-cipher/rotational_cipher_test.rb b/exercises/practice/rotational-cipher/rotational_cipher_test.rb similarity index 100% rename from exercises/rotational-cipher/rotational_cipher_test.rb rename to exercises/practice/rotational-cipher/rotational_cipher_test.rb diff --git a/exercises/run-length-encoding/.meta/generator/run_length_encoding_case.rb b/exercises/practice/run-length-encoding/.meta/generator/run_length_encoding_case.rb similarity index 100% rename from exercises/run-length-encoding/.meta/generator/run_length_encoding_case.rb rename to exercises/practice/run-length-encoding/.meta/generator/run_length_encoding_case.rb diff --git a/exercises/run-length-encoding/.meta/solutions/run_length_encoding.rb b/exercises/practice/run-length-encoding/.meta/solutions/run_length_encoding.rb similarity index 100% rename from exercises/run-length-encoding/.meta/solutions/run_length_encoding.rb rename to exercises/practice/run-length-encoding/.meta/solutions/run_length_encoding.rb diff --git a/exercises/run-length-encoding/.meta/tests.toml b/exercises/practice/run-length-encoding/.meta/tests.toml similarity index 100% rename from exercises/run-length-encoding/.meta/tests.toml rename to exercises/practice/run-length-encoding/.meta/tests.toml diff --git a/exercises/run-length-encoding/README.md b/exercises/practice/run-length-encoding/README.md similarity index 100% rename from exercises/run-length-encoding/README.md rename to exercises/practice/run-length-encoding/README.md diff --git a/exercises/run-length-encoding/run_length_encoding.rb b/exercises/practice/run-length-encoding/run_length_encoding.rb similarity index 100% rename from exercises/run-length-encoding/run_length_encoding.rb rename to exercises/practice/run-length-encoding/run_length_encoding.rb diff --git a/exercises/run-length-encoding/run_length_encoding_test.rb b/exercises/practice/run-length-encoding/run_length_encoding_test.rb similarity index 100% rename from exercises/run-length-encoding/run_length_encoding_test.rb rename to exercises/practice/run-length-encoding/run_length_encoding_test.rb diff --git a/exercises/saddle-points/.meta/solutions/saddle_points.rb b/exercises/practice/saddle-points/.meta/solutions/saddle_points.rb similarity index 100% rename from exercises/saddle-points/.meta/solutions/saddle_points.rb rename to exercises/practice/saddle-points/.meta/solutions/saddle_points.rb diff --git a/exercises/saddle-points/.meta/tests.toml b/exercises/practice/saddle-points/.meta/tests.toml similarity index 100% rename from exercises/saddle-points/.meta/tests.toml rename to exercises/practice/saddle-points/.meta/tests.toml diff --git a/exercises/saddle-points/README.md b/exercises/practice/saddle-points/README.md similarity index 100% rename from exercises/saddle-points/README.md rename to exercises/practice/saddle-points/README.md diff --git a/exercises/saddle-points/saddle_points.rb b/exercises/practice/saddle-points/saddle_points.rb similarity index 100% rename from exercises/saddle-points/saddle_points.rb rename to exercises/practice/saddle-points/saddle_points.rb diff --git a/exercises/saddle-points/saddle_points_test.rb b/exercises/practice/saddle-points/saddle_points_test.rb similarity index 100% rename from exercises/saddle-points/saddle_points_test.rb rename to exercises/practice/saddle-points/saddle_points_test.rb diff --git a/exercises/say/.meta/generator/say_case.rb b/exercises/practice/say/.meta/generator/say_case.rb similarity index 100% rename from exercises/say/.meta/generator/say_case.rb rename to exercises/practice/say/.meta/generator/say_case.rb diff --git a/exercises/say/.meta/solutions/say.rb b/exercises/practice/say/.meta/solutions/say.rb similarity index 100% rename from exercises/say/.meta/solutions/say.rb rename to exercises/practice/say/.meta/solutions/say.rb diff --git a/exercises/say/.meta/tests.toml b/exercises/practice/say/.meta/tests.toml similarity index 100% rename from exercises/say/.meta/tests.toml rename to exercises/practice/say/.meta/tests.toml diff --git a/exercises/say/README.md b/exercises/practice/say/README.md similarity index 100% rename from exercises/say/README.md rename to exercises/practice/say/README.md diff --git a/exercises/say/say.rb b/exercises/practice/say/say.rb similarity index 100% rename from exercises/say/say.rb rename to exercises/practice/say/say.rb diff --git a/exercises/say/say_test.rb b/exercises/practice/say/say_test.rb similarity index 100% rename from exercises/say/say_test.rb rename to exercises/practice/say/say_test.rb diff --git a/exercises/scale-generator/.meta/solutions/scale_generator.rb b/exercises/practice/scale-generator/.meta/solutions/scale_generator.rb similarity index 100% rename from exercises/scale-generator/.meta/solutions/scale_generator.rb rename to exercises/practice/scale-generator/.meta/solutions/scale_generator.rb diff --git a/exercises/scale-generator/.meta/tests.toml b/exercises/practice/scale-generator/.meta/tests.toml similarity index 100% rename from exercises/scale-generator/.meta/tests.toml rename to exercises/practice/scale-generator/.meta/tests.toml diff --git a/exercises/scale-generator/README.md b/exercises/practice/scale-generator/README.md similarity index 100% rename from exercises/scale-generator/README.md rename to exercises/practice/scale-generator/README.md diff --git a/exercises/scale-generator/scale_generator.rb b/exercises/practice/scale-generator/scale_generator.rb similarity index 100% rename from exercises/scale-generator/scale_generator.rb rename to exercises/practice/scale-generator/scale_generator.rb diff --git a/exercises/scale-generator/scale_generator_test.rb b/exercises/practice/scale-generator/scale_generator_test.rb similarity index 100% rename from exercises/scale-generator/scale_generator_test.rb rename to exercises/practice/scale-generator/scale_generator_test.rb diff --git a/exercises/scrabble-score/.meta/solutions/scrabble_score.rb b/exercises/practice/scrabble-score/.meta/solutions/scrabble_score.rb similarity index 100% rename from exercises/scrabble-score/.meta/solutions/scrabble_score.rb rename to exercises/practice/scrabble-score/.meta/solutions/scrabble_score.rb diff --git a/exercises/scrabble-score/.meta/tests.toml b/exercises/practice/scrabble-score/.meta/tests.toml similarity index 100% rename from exercises/scrabble-score/.meta/tests.toml rename to exercises/practice/scrabble-score/.meta/tests.toml diff --git a/exercises/scrabble-score/README.md b/exercises/practice/scrabble-score/README.md similarity index 100% rename from exercises/scrabble-score/README.md rename to exercises/practice/scrabble-score/README.md diff --git a/exercises/scrabble-score/scrabble_score.rb b/exercises/practice/scrabble-score/scrabble_score.rb similarity index 100% rename from exercises/scrabble-score/scrabble_score.rb rename to exercises/practice/scrabble-score/scrabble_score.rb diff --git a/exercises/scrabble-score/scrabble_score_test.rb b/exercises/practice/scrabble-score/scrabble_score_test.rb similarity index 100% rename from exercises/scrabble-score/scrabble_score_test.rb rename to exercises/practice/scrabble-score/scrabble_score_test.rb diff --git a/exercises/secret-handshake/.meta/solutions/secret_handshake.rb b/exercises/practice/secret-handshake/.meta/solutions/secret_handshake.rb similarity index 100% rename from exercises/secret-handshake/.meta/solutions/secret_handshake.rb rename to exercises/practice/secret-handshake/.meta/solutions/secret_handshake.rb diff --git a/exercises/secret-handshake/.meta/tests.toml b/exercises/practice/secret-handshake/.meta/tests.toml similarity index 100% rename from exercises/secret-handshake/.meta/tests.toml rename to exercises/practice/secret-handshake/.meta/tests.toml diff --git a/exercises/secret-handshake/README.md b/exercises/practice/secret-handshake/README.md similarity index 100% rename from exercises/secret-handshake/README.md rename to exercises/practice/secret-handshake/README.md diff --git a/exercises/secret-handshake/secret_handshake.rb b/exercises/practice/secret-handshake/secret_handshake.rb similarity index 100% rename from exercises/secret-handshake/secret_handshake.rb rename to exercises/practice/secret-handshake/secret_handshake.rb diff --git a/exercises/secret-handshake/secret_handshake_test.rb b/exercises/practice/secret-handshake/secret_handshake_test.rb similarity index 100% rename from exercises/secret-handshake/secret_handshake_test.rb rename to exercises/practice/secret-handshake/secret_handshake_test.rb diff --git a/exercises/series/.meta/hints.md b/exercises/practice/series/.meta/hints.md similarity index 100% rename from exercises/series/.meta/hints.md rename to exercises/practice/series/.meta/hints.md diff --git a/exercises/series/.meta/solutions/series.rb b/exercises/practice/series/.meta/solutions/series.rb similarity index 100% rename from exercises/series/.meta/solutions/series.rb rename to exercises/practice/series/.meta/solutions/series.rb diff --git a/exercises/series/.meta/tests.toml b/exercises/practice/series/.meta/tests.toml similarity index 100% rename from exercises/series/.meta/tests.toml rename to exercises/practice/series/.meta/tests.toml diff --git a/exercises/series/README.md b/exercises/practice/series/README.md similarity index 100% rename from exercises/series/README.md rename to exercises/practice/series/README.md diff --git a/exercises/series/series.rb b/exercises/practice/series/series.rb similarity index 100% rename from exercises/series/series.rb rename to exercises/practice/series/series.rb diff --git a/exercises/series/series_test.rb b/exercises/practice/series/series_test.rb similarity index 100% rename from exercises/series/series_test.rb rename to exercises/practice/series/series_test.rb diff --git a/exercises/sieve/.meta/generator/sieve_case.rb b/exercises/practice/sieve/.meta/generator/sieve_case.rb similarity index 100% rename from exercises/sieve/.meta/generator/sieve_case.rb rename to exercises/practice/sieve/.meta/generator/sieve_case.rb diff --git a/exercises/sieve/.meta/solutions/sieve.rb b/exercises/practice/sieve/.meta/solutions/sieve.rb similarity index 100% rename from exercises/sieve/.meta/solutions/sieve.rb rename to exercises/practice/sieve/.meta/solutions/sieve.rb diff --git a/exercises/sieve/.meta/tests.toml b/exercises/practice/sieve/.meta/tests.toml similarity index 100% rename from exercises/sieve/.meta/tests.toml rename to exercises/practice/sieve/.meta/tests.toml diff --git a/exercises/sieve/README.md b/exercises/practice/sieve/README.md similarity index 100% rename from exercises/sieve/README.md rename to exercises/practice/sieve/README.md diff --git a/exercises/sieve/sieve.rb b/exercises/practice/sieve/sieve.rb similarity index 100% rename from exercises/sieve/sieve.rb rename to exercises/practice/sieve/sieve.rb diff --git a/exercises/sieve/sieve_test.rb b/exercises/practice/sieve/sieve_test.rb similarity index 100% rename from exercises/sieve/sieve_test.rb rename to exercises/practice/sieve/sieve_test.rb diff --git a/exercises/simple-cipher/.meta/solutions/simple_cipher.rb b/exercises/practice/simple-cipher/.meta/solutions/simple_cipher.rb similarity index 100% rename from exercises/simple-cipher/.meta/solutions/simple_cipher.rb rename to exercises/practice/simple-cipher/.meta/solutions/simple_cipher.rb diff --git a/exercises/simple-cipher/.meta/tests.toml b/exercises/practice/simple-cipher/.meta/tests.toml similarity index 100% rename from exercises/simple-cipher/.meta/tests.toml rename to exercises/practice/simple-cipher/.meta/tests.toml diff --git a/exercises/simple-cipher/README.md b/exercises/practice/simple-cipher/README.md similarity index 100% rename from exercises/simple-cipher/README.md rename to exercises/practice/simple-cipher/README.md diff --git a/exercises/simple-cipher/simple_cipher.rb b/exercises/practice/simple-cipher/simple_cipher.rb similarity index 100% rename from exercises/simple-cipher/simple_cipher.rb rename to exercises/practice/simple-cipher/simple_cipher.rb diff --git a/exercises/simple-cipher/simple_cipher_test.rb b/exercises/practice/simple-cipher/simple_cipher_test.rb similarity index 100% rename from exercises/simple-cipher/simple_cipher_test.rb rename to exercises/practice/simple-cipher/simple_cipher_test.rb diff --git a/exercises/simple-linked-list/.meta/solutions/simple_linked_list.rb b/exercises/practice/simple-linked-list/.meta/solutions/simple_linked_list.rb similarity index 100% rename from exercises/simple-linked-list/.meta/solutions/simple_linked_list.rb rename to exercises/practice/simple-linked-list/.meta/solutions/simple_linked_list.rb diff --git a/exercises/simple-linked-list/README.md b/exercises/practice/simple-linked-list/README.md similarity index 100% rename from exercises/simple-linked-list/README.md rename to exercises/practice/simple-linked-list/README.md diff --git a/exercises/simple-linked-list/simple_linked_list.rb b/exercises/practice/simple-linked-list/simple_linked_list.rb similarity index 100% rename from exercises/simple-linked-list/simple_linked_list.rb rename to exercises/practice/simple-linked-list/simple_linked_list.rb diff --git a/exercises/simple-linked-list/simple_linked_list_test.rb b/exercises/practice/simple-linked-list/simple_linked_list_test.rb similarity index 100% rename from exercises/simple-linked-list/simple_linked_list_test.rb rename to exercises/practice/simple-linked-list/simple_linked_list_test.rb diff --git a/exercises/space-age/.meta/generator/space_age_case.rb b/exercises/practice/space-age/.meta/generator/space_age_case.rb similarity index 100% rename from exercises/space-age/.meta/generator/space_age_case.rb rename to exercises/practice/space-age/.meta/generator/space_age_case.rb diff --git a/exercises/space-age/.meta/generator/test_template.erb b/exercises/practice/space-age/.meta/generator/test_template.erb similarity index 100% rename from exercises/space-age/.meta/generator/test_template.erb rename to exercises/practice/space-age/.meta/generator/test_template.erb diff --git a/exercises/space-age/.meta/solutions/space_age.rb b/exercises/practice/space-age/.meta/solutions/space_age.rb similarity index 100% rename from exercises/space-age/.meta/solutions/space_age.rb rename to exercises/practice/space-age/.meta/solutions/space_age.rb diff --git a/exercises/space-age/.meta/tests.toml b/exercises/practice/space-age/.meta/tests.toml similarity index 100% rename from exercises/space-age/.meta/tests.toml rename to exercises/practice/space-age/.meta/tests.toml diff --git a/exercises/space-age/README.md b/exercises/practice/space-age/README.md similarity index 100% rename from exercises/space-age/README.md rename to exercises/practice/space-age/README.md diff --git a/exercises/space-age/space_age.rb b/exercises/practice/space-age/space_age.rb similarity index 100% rename from exercises/space-age/space_age.rb rename to exercises/practice/space-age/space_age.rb diff --git a/exercises/space-age/space_age_test.rb b/exercises/practice/space-age/space_age_test.rb similarity index 100% rename from exercises/space-age/space_age_test.rb rename to exercises/practice/space-age/space_age_test.rb diff --git a/exercises/strain/.meta/solutions/strain.rb b/exercises/practice/strain/.meta/solutions/strain.rb similarity index 100% rename from exercises/strain/.meta/solutions/strain.rb rename to exercises/practice/strain/.meta/solutions/strain.rb diff --git a/exercises/strain/README.md b/exercises/practice/strain/README.md similarity index 100% rename from exercises/strain/README.md rename to exercises/practice/strain/README.md diff --git a/exercises/strain/strain.rb b/exercises/practice/strain/strain.rb similarity index 100% rename from exercises/strain/strain.rb rename to exercises/practice/strain/strain.rb diff --git a/exercises/strain/strain_test.rb b/exercises/practice/strain/strain_test.rb similarity index 100% rename from exercises/strain/strain_test.rb rename to exercises/practice/strain/strain_test.rb diff --git a/exercises/sum-of-multiples/.meta/generator/sum_of_multiples_case.rb b/exercises/practice/sum-of-multiples/.meta/generator/sum_of_multiples_case.rb similarity index 100% rename from exercises/sum-of-multiples/.meta/generator/sum_of_multiples_case.rb rename to exercises/practice/sum-of-multiples/.meta/generator/sum_of_multiples_case.rb diff --git a/exercises/sum-of-multiples/.meta/solutions/sum_of_multiples.rb b/exercises/practice/sum-of-multiples/.meta/solutions/sum_of_multiples.rb similarity index 100% rename from exercises/sum-of-multiples/.meta/solutions/sum_of_multiples.rb rename to exercises/practice/sum-of-multiples/.meta/solutions/sum_of_multiples.rb diff --git a/exercises/sum-of-multiples/.meta/tests.toml b/exercises/practice/sum-of-multiples/.meta/tests.toml similarity index 100% rename from exercises/sum-of-multiples/.meta/tests.toml rename to exercises/practice/sum-of-multiples/.meta/tests.toml diff --git a/exercises/sum-of-multiples/README.md b/exercises/practice/sum-of-multiples/README.md similarity index 100% rename from exercises/sum-of-multiples/README.md rename to exercises/practice/sum-of-multiples/README.md diff --git a/exercises/sum-of-multiples/sum_of_multiples.rb b/exercises/practice/sum-of-multiples/sum_of_multiples.rb similarity index 100% rename from exercises/sum-of-multiples/sum_of_multiples.rb rename to exercises/practice/sum-of-multiples/sum_of_multiples.rb diff --git a/exercises/sum-of-multiples/sum_of_multiples_test.rb b/exercises/practice/sum-of-multiples/sum_of_multiples_test.rb similarity index 100% rename from exercises/sum-of-multiples/sum_of_multiples_test.rb rename to exercises/practice/sum-of-multiples/sum_of_multiples_test.rb diff --git a/exercises/tournament/.meta/generator/tournament_case.rb b/exercises/practice/tournament/.meta/generator/tournament_case.rb similarity index 100% rename from exercises/tournament/.meta/generator/tournament_case.rb rename to exercises/practice/tournament/.meta/generator/tournament_case.rb diff --git a/exercises/tournament/.meta/solutions/tournament.rb b/exercises/practice/tournament/.meta/solutions/tournament.rb similarity index 100% rename from exercises/tournament/.meta/solutions/tournament.rb rename to exercises/practice/tournament/.meta/solutions/tournament.rb diff --git a/exercises/tournament/.meta/tests.toml b/exercises/practice/tournament/.meta/tests.toml similarity index 100% rename from exercises/tournament/.meta/tests.toml rename to exercises/practice/tournament/.meta/tests.toml diff --git a/exercises/tournament/README.md b/exercises/practice/tournament/README.md similarity index 100% rename from exercises/tournament/README.md rename to exercises/practice/tournament/README.md diff --git a/exercises/tournament/tournament.rb b/exercises/practice/tournament/tournament.rb similarity index 100% rename from exercises/tournament/tournament.rb rename to exercises/practice/tournament/tournament.rb diff --git a/exercises/tournament/tournament_test.rb b/exercises/practice/tournament/tournament_test.rb similarity index 100% rename from exercises/tournament/tournament_test.rb rename to exercises/practice/tournament/tournament_test.rb diff --git a/exercises/transpose/.meta/generator/transpose_case.rb b/exercises/practice/transpose/.meta/generator/transpose_case.rb similarity index 100% rename from exercises/transpose/.meta/generator/transpose_case.rb rename to exercises/practice/transpose/.meta/generator/transpose_case.rb diff --git a/exercises/transpose/.meta/solutions/transpose.rb b/exercises/practice/transpose/.meta/solutions/transpose.rb similarity index 100% rename from exercises/transpose/.meta/solutions/transpose.rb rename to exercises/practice/transpose/.meta/solutions/transpose.rb diff --git a/exercises/transpose/.meta/tests.toml b/exercises/practice/transpose/.meta/tests.toml similarity index 100% rename from exercises/transpose/.meta/tests.toml rename to exercises/practice/transpose/.meta/tests.toml diff --git a/exercises/transpose/README.md b/exercises/practice/transpose/README.md similarity index 100% rename from exercises/transpose/README.md rename to exercises/practice/transpose/README.md diff --git a/exercises/transpose/transpose.rb b/exercises/practice/transpose/transpose.rb similarity index 100% rename from exercises/transpose/transpose.rb rename to exercises/practice/transpose/transpose.rb diff --git a/exercises/transpose/transpose_test.rb b/exercises/practice/transpose/transpose_test.rb similarity index 100% rename from exercises/transpose/transpose_test.rb rename to exercises/practice/transpose/transpose_test.rb diff --git a/exercises/triangle/.meta/generator/triangle_case.rb b/exercises/practice/triangle/.meta/generator/triangle_case.rb similarity index 100% rename from exercises/triangle/.meta/generator/triangle_case.rb rename to exercises/practice/triangle/.meta/generator/triangle_case.rb diff --git a/exercises/triangle/.meta/solutions/triangle.rb b/exercises/practice/triangle/.meta/solutions/triangle.rb similarity index 100% rename from exercises/triangle/.meta/solutions/triangle.rb rename to exercises/practice/triangle/.meta/solutions/triangle.rb diff --git a/exercises/triangle/.meta/tests.toml b/exercises/practice/triangle/.meta/tests.toml similarity index 100% rename from exercises/triangle/.meta/tests.toml rename to exercises/practice/triangle/.meta/tests.toml diff --git a/exercises/triangle/README.md b/exercises/practice/triangle/README.md similarity index 100% rename from exercises/triangle/README.md rename to exercises/practice/triangle/README.md diff --git a/exercises/triangle/triangle.rb b/exercises/practice/triangle/triangle.rb similarity index 100% rename from exercises/triangle/triangle.rb rename to exercises/practice/triangle/triangle.rb diff --git a/exercises/triangle/triangle_test.rb b/exercises/practice/triangle/triangle_test.rb similarity index 100% rename from exercises/triangle/triangle_test.rb rename to exercises/practice/triangle/triangle_test.rb diff --git a/exercises/trinary/.meta/solutions/trinary.rb b/exercises/practice/trinary/.meta/solutions/trinary.rb similarity index 100% rename from exercises/trinary/.meta/solutions/trinary.rb rename to exercises/practice/trinary/.meta/solutions/trinary.rb diff --git a/exercises/trinary/.meta/tests.toml b/exercises/practice/trinary/.meta/tests.toml similarity index 100% rename from exercises/trinary/.meta/tests.toml rename to exercises/practice/trinary/.meta/tests.toml diff --git a/exercises/trinary/README.md b/exercises/practice/trinary/README.md similarity index 100% rename from exercises/trinary/README.md rename to exercises/practice/trinary/README.md diff --git a/exercises/trinary/trinary.rb b/exercises/practice/trinary/trinary.rb similarity index 100% rename from exercises/trinary/trinary.rb rename to exercises/practice/trinary/trinary.rb diff --git a/exercises/trinary/trinary_test.rb b/exercises/practice/trinary/trinary_test.rb similarity index 100% rename from exercises/trinary/trinary_test.rb rename to exercises/practice/trinary/trinary_test.rb diff --git a/exercises/twelve-days/.meta/solutions/twelve_days.rb b/exercises/practice/twelve-days/.meta/solutions/twelve_days.rb similarity index 100% rename from exercises/twelve-days/.meta/solutions/twelve_days.rb rename to exercises/practice/twelve-days/.meta/solutions/twelve_days.rb diff --git a/exercises/twelve-days/.meta/tests.toml b/exercises/practice/twelve-days/.meta/tests.toml similarity index 100% rename from exercises/twelve-days/.meta/tests.toml rename to exercises/practice/twelve-days/.meta/tests.toml diff --git a/exercises/twelve-days/README.md b/exercises/practice/twelve-days/README.md similarity index 100% rename from exercises/twelve-days/README.md rename to exercises/practice/twelve-days/README.md diff --git a/exercises/twelve-days/song.txt b/exercises/practice/twelve-days/song.txt similarity index 100% rename from exercises/twelve-days/song.txt rename to exercises/practice/twelve-days/song.txt diff --git a/exercises/twelve-days/twelve_days.rb b/exercises/practice/twelve-days/twelve_days.rb similarity index 100% rename from exercises/twelve-days/twelve_days.rb rename to exercises/practice/twelve-days/twelve_days.rb diff --git a/exercises/twelve-days/twelve_days_test.rb b/exercises/practice/twelve-days/twelve_days_test.rb similarity index 100% rename from exercises/twelve-days/twelve_days_test.rb rename to exercises/practice/twelve-days/twelve_days_test.rb diff --git a/exercises/two-bucket/.meta/generator/two_bucket_case.rb b/exercises/practice/two-bucket/.meta/generator/two_bucket_case.rb similarity index 100% rename from exercises/two-bucket/.meta/generator/two_bucket_case.rb rename to exercises/practice/two-bucket/.meta/generator/two_bucket_case.rb diff --git a/exercises/two-bucket/.meta/solutions/two_bucket.rb b/exercises/practice/two-bucket/.meta/solutions/two_bucket.rb similarity index 100% rename from exercises/two-bucket/.meta/solutions/two_bucket.rb rename to exercises/practice/two-bucket/.meta/solutions/two_bucket.rb diff --git a/exercises/two-bucket/.meta/tests.toml b/exercises/practice/two-bucket/.meta/tests.toml similarity index 100% rename from exercises/two-bucket/.meta/tests.toml rename to exercises/practice/two-bucket/.meta/tests.toml diff --git a/exercises/two-bucket/README.md b/exercises/practice/two-bucket/README.md similarity index 100% rename from exercises/two-bucket/README.md rename to exercises/practice/two-bucket/README.md diff --git a/exercises/two-bucket/two_bucket.rb b/exercises/practice/two-bucket/two_bucket.rb similarity index 100% rename from exercises/two-bucket/two_bucket.rb rename to exercises/practice/two-bucket/two_bucket.rb diff --git a/exercises/two-bucket/two_bucket_test.rb b/exercises/practice/two-bucket/two_bucket_test.rb similarity index 100% rename from exercises/two-bucket/two_bucket_test.rb rename to exercises/practice/two-bucket/two_bucket_test.rb diff --git a/exercises/two-fer/.meta/generator/two_fer_case.rb b/exercises/practice/two-fer/.meta/generator/two_fer_case.rb similarity index 100% rename from exercises/two-fer/.meta/generator/two_fer_case.rb rename to exercises/practice/two-fer/.meta/generator/two_fer_case.rb diff --git a/exercises/two-fer/.meta/solutions/two_fer.rb b/exercises/practice/two-fer/.meta/solutions/two_fer.rb similarity index 100% rename from exercises/two-fer/.meta/solutions/two_fer.rb rename to exercises/practice/two-fer/.meta/solutions/two_fer.rb diff --git a/exercises/two-fer/.meta/tests.toml b/exercises/practice/two-fer/.meta/tests.toml similarity index 100% rename from exercises/two-fer/.meta/tests.toml rename to exercises/practice/two-fer/.meta/tests.toml diff --git a/exercises/two-fer/README.md b/exercises/practice/two-fer/README.md similarity index 100% rename from exercises/two-fer/README.md rename to exercises/practice/two-fer/README.md diff --git a/exercises/two-fer/two_fer.rb b/exercises/practice/two-fer/two_fer.rb similarity index 100% rename from exercises/two-fer/two_fer.rb rename to exercises/practice/two-fer/two_fer.rb diff --git a/exercises/two-fer/two_fer_test.rb b/exercises/practice/two-fer/two_fer_test.rb similarity index 100% rename from exercises/two-fer/two_fer_test.rb rename to exercises/practice/two-fer/two_fer_test.rb diff --git a/exercises/word-count/.meta/generator/word_count_case.rb b/exercises/practice/word-count/.meta/generator/word_count_case.rb similarity index 100% rename from exercises/word-count/.meta/generator/word_count_case.rb rename to exercises/practice/word-count/.meta/generator/word_count_case.rb diff --git a/exercises/word-count/.meta/solutions/word_count.rb b/exercises/practice/word-count/.meta/solutions/word_count.rb similarity index 100% rename from exercises/word-count/.meta/solutions/word_count.rb rename to exercises/practice/word-count/.meta/solutions/word_count.rb diff --git a/exercises/word-count/.meta/tests.toml b/exercises/practice/word-count/.meta/tests.toml similarity index 100% rename from exercises/word-count/.meta/tests.toml rename to exercises/practice/word-count/.meta/tests.toml diff --git a/exercises/word-count/README.md b/exercises/practice/word-count/README.md similarity index 100% rename from exercises/word-count/README.md rename to exercises/practice/word-count/README.md diff --git a/exercises/word-count/word_count.rb b/exercises/practice/word-count/word_count.rb similarity index 100% rename from exercises/word-count/word_count.rb rename to exercises/practice/word-count/word_count.rb diff --git a/exercises/word-count/word_count_test.rb b/exercises/practice/word-count/word_count_test.rb similarity index 100% rename from exercises/word-count/word_count_test.rb rename to exercises/practice/word-count/word_count_test.rb diff --git a/exercises/wordy/.meta/generator/wordy_case.rb b/exercises/practice/wordy/.meta/generator/wordy_case.rb similarity index 100% rename from exercises/wordy/.meta/generator/wordy_case.rb rename to exercises/practice/wordy/.meta/generator/wordy_case.rb diff --git a/exercises/wordy/.meta/solutions/wordy.rb b/exercises/practice/wordy/.meta/solutions/wordy.rb similarity index 100% rename from exercises/wordy/.meta/solutions/wordy.rb rename to exercises/practice/wordy/.meta/solutions/wordy.rb diff --git a/exercises/wordy/.meta/tests.toml b/exercises/practice/wordy/.meta/tests.toml similarity index 100% rename from exercises/wordy/.meta/tests.toml rename to exercises/practice/wordy/.meta/tests.toml diff --git a/exercises/wordy/README.md b/exercises/practice/wordy/README.md similarity index 100% rename from exercises/wordy/README.md rename to exercises/practice/wordy/README.md diff --git a/exercises/wordy/wordy.rb b/exercises/practice/wordy/wordy.rb similarity index 100% rename from exercises/wordy/wordy.rb rename to exercises/practice/wordy/wordy.rb diff --git a/exercises/wordy/wordy_test.rb b/exercises/practice/wordy/wordy_test.rb similarity index 100% rename from exercises/wordy/wordy_test.rb rename to exercises/practice/wordy/wordy_test.rb diff --git a/exercises/zipper/.meta/generator/zipper_case.rb b/exercises/practice/zipper/.meta/generator/zipper_case.rb similarity index 100% rename from exercises/zipper/.meta/generator/zipper_case.rb rename to exercises/practice/zipper/.meta/generator/zipper_case.rb diff --git a/exercises/zipper/.meta/solutions/zipper.rb b/exercises/practice/zipper/.meta/solutions/zipper.rb similarity index 100% rename from exercises/zipper/.meta/solutions/zipper.rb rename to exercises/practice/zipper/.meta/solutions/zipper.rb diff --git a/exercises/zipper/.meta/tests.toml b/exercises/practice/zipper/.meta/tests.toml similarity index 100% rename from exercises/zipper/.meta/tests.toml rename to exercises/practice/zipper/.meta/tests.toml diff --git a/exercises/zipper/README.md b/exercises/practice/zipper/README.md similarity index 100% rename from exercises/zipper/README.md rename to exercises/practice/zipper/README.md diff --git a/exercises/zipper/zipper.rb b/exercises/practice/zipper/zipper.rb similarity index 100% rename from exercises/zipper/zipper.rb rename to exercises/practice/zipper/zipper.rb diff --git a/exercises/zipper/zipper_test.rb b/exercises/practice/zipper/zipper_test.rb similarity index 100% rename from exercises/zipper/zipper_test.rb rename to exercises/practice/zipper/zipper_test.rb From 69fe535415869cbb55800953569de08cc1081a52 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:44 +0100 Subject: [PATCH 084/102] [v3] Add version property to config.json --- config.json | 1 + 1 file changed, 1 insertion(+) diff --git a/config.json b/config.json index 753f4e6390..f53a41e31f 100644 --- a/config.json +++ b/config.json @@ -2,6 +2,7 @@ "language": "Ruby", "active": true, "blurb": "Ruby is a dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.", + "version": 3, "gitter": "ruby", "solution_pattern": "[Ee]xample|\\.meta/solutions/[^/]*\\.rb", "online_editor": { From 43409e2d109815aa8a482f21f1e5157c955d3e62 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:44 +0100 Subject: [PATCH 085/102] [v3] Add status to config.json --- config.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config.json b/config.json index f53a41e31f..6ddafc5c55 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,12 @@ { "language": "Ruby", "active": true, + "status": { + "concept_exercises": false, + "test_runner": false, + "representer": false, + "analyzer": false + }, "blurb": "Ruby is a dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.", "version": 3, "gitter": "ruby", From eb27bf2b62d070afaa0aa7e79aaeb88d36ef0211 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:45 +0100 Subject: [PATCH 086/102] [v3] Add slug to config.json --- config.json | 1 + 1 file changed, 1 insertion(+) diff --git a/config.json b/config.json index 6ddafc5c55..c9e8980094 100644 --- a/config.json +++ b/config.json @@ -1,5 +1,6 @@ { "language": "Ruby", + "slug": "ruby", "active": true, "status": { "concept_exercises": false, From 412135d4a831b8baabc60060483176b42c1a5da0 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:45 +0100 Subject: [PATCH 087/102] [v3] Add status for deprecated practice exercises in config.json --- config.json | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/config.json b/config.json index c9e8980094..09ff8e5229 100644 --- a/config.json +++ b/config.json @@ -366,7 +366,8 @@ "unlocked_by": null, "difficulty": 0, "topics": null, - "deprecated": true + "deprecated": true, + "status": "deprecated" }, { "slug": "accumulate", @@ -458,7 +459,8 @@ "unlocked_by": null, "difficulty": 0, "topics": null, - "deprecated": true + "deprecated": true, + "status": "deprecated" }, { "slug": "beer-song", @@ -595,7 +597,8 @@ "unlocked_by": null, "difficulty": 0, "topics": null, - "deprecated": true + "deprecated": true, + "status": "deprecated" }, { "slug": "say", @@ -1153,7 +1156,8 @@ "unlocked_by": null, "difficulty": 0, "topics": null, - "deprecated": true + "deprecated": true, + "status": "deprecated" }, { "slug": "affine-cipher", @@ -1184,7 +1188,8 @@ "unlocked_by": null, "difficulty": 0, "topics": null, - "deprecated": true + "deprecated": true, + "status": "deprecated" }, { "slug": "zipper", From 3ff27c73b15ff509d4d9201c115919a3ba08c822 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:45 +0100 Subject: [PATCH 088/102] [v3] Re-order practice exercises in config.json --- config.json | 1088 +++++++++++++++++++++++++-------------------------- 1 file changed, 544 insertions(+), 544 deletions(-) diff --git a/config.json b/config.json index 09ff8e5229..316ee8403e 100644 --- a/config.json +++ b/config.json @@ -212,27 +212,6 @@ "transforming" ] }, - { - "slug": "armstrong-numbers", - "uuid": "77c5c7e6-265a-4f1a-9bc4-851f8f825420", - "core": false, - "unlocked_by": "series", - "difficulty": 3, - "topics": [ - "math" - ] - }, - { - "slug": "difference-of-squares", - "uuid": "f1e4ee0c-8718-43f2-90a5-fb1e915288da", - "core": false, - "unlocked_by": "matrix", - "difficulty": 2, - "topics": [ - "algorithms", - "math" - ] - }, { "slug": "gigasecond", "uuid": "0fb594a1-193b-4ccf-8de2-eb6a81708b29", @@ -244,14 +223,13 @@ ] }, { - "slug": "grains", - "uuid": "22519f53-4516-43bc-915e-07d58e48f617", + "slug": "resistor-color", + "uuid": "685634dd-0b38-40bc-b0ad-e8aa2904035f", "core": false, - "unlocked_by": "series", - "difficulty": 4, + "unlocked_by": "hello-world", + "difficulty": 1, "topics": [ - "bitwise_operations", - "math" + "arrays" ] }, { @@ -266,13 +244,16 @@ ] }, { - "slug": "robot-name", - "uuid": "76a0fd0a-cc65-4be3-acc8-7348bb67ad5a", + "slug": "leap", + "uuid": "06eaa2dd-dc80-4d38-b10d-11174183b0b6", "core": false, - "unlocked_by": "luhn", - "difficulty": 3, + "unlocked_by": "resistor-color-duo", + "difficulty": 1, "topics": [ - "randomness" + "booleans", + "conditionals", + "integers", + "logic" ] }, { @@ -287,119 +268,94 @@ ] }, { - "slug": "sieve", - "uuid": "80f9af5a-ea29-4937-9333-b4494aaf2446", - "core": false, - "unlocked_by": "hamming", - "difficulty": 3, - "topics": [ - "algorithms", - "integers", - "loops", - "math", - "sorting" - ] - }, - { - "slug": "roman-numerals", - "uuid": "b7ca9519-c33b-418b-a4ef-858a3d4d6855", + "slug": "space-age", + "uuid": "c971a2b5-ccd4-4e55-9fc7-33e991bc0676", "core": false, - "unlocked_by": "clock", + "unlocked_by": "acronym", "difficulty": 2, "topics": [ - "numbers", - "transforming" + "floating_point_numbers", + "if_else_statements" ] }, { - "slug": "nth-prime", - "uuid": "16baef71-6234-4928-a2d4-a19eb8e110b8", + "slug": "triangle", + "uuid": "5c797eb2-155d-47ca-8f85-2ba5803f9713", "core": false, - "unlocked_by": "raindrops", + "unlocked_by": "high-scores", "difficulty": 3, - "topics": [ - "algorithms", - "integers", - "math" - ] - }, - { - "slug": "leap", - "uuid": "06eaa2dd-dc80-4d38-b10d-11174183b0b6", - "core": false, - "unlocked_by": "resistor-color-duo", - "difficulty": 1, "topics": [ "booleans", "conditionals", - "integers", "logic" ] }, { - "slug": "bob", - "uuid": "70fec82e-3038-468f-96ef-bfb48ce03ef3", + "slug": "difference-of-squares", + "uuid": "f1e4ee0c-8718-43f2-90a5-fb1e915288da", "core": false, - "unlocked_by": "raindrops", + "unlocked_by": "matrix", "difficulty": 2, "topics": [ - "conditionals", - "strings" + "algorithms", + "math" ] }, { - "slug": "run-length-encoding", - "uuid": "9d6a8c89-41c1-4c4e-b24c-476ba0dfa5f9", + "slug": "anagram", + "uuid": "36df18ba-580d-4982-984e-ba50eb1f8c0b", "core": false, - "unlocked_by": "isogram", - "difficulty": 4, + "unlocked_by": "matrix", + "difficulty": 5, "topics": [ + "filtering", "parsing", - "strings", - "transforming" + "sorting", + "strings" ] }, { - "slug": "binary", - "uuid": "43bc27ed-d2fa-4173-8665-4459b71c9a3a", - "core": false, - "unlocked_by": null, - "difficulty": 0, - "topics": null, - "deprecated": true, - "status": "deprecated" - }, - { - "slug": "accumulate", - "uuid": "2c71fc3a-2c93-402b-b091-697b795ce3ba", + "slug": "sum-of-multiples", + "uuid": "4fc25295-5d6a-4d13-9b87-064167d8980e", "core": false, - "unlocked_by": "raindrops", - "difficulty": 1, + "unlocked_by": "matrix", + "difficulty": 5, "topics": [ - "lists" + "loops", + "math" ] }, { - "slug": "sum-of-multiples", - "uuid": "4fc25295-5d6a-4d13-9b87-064167d8980e", + "slug": "transpose", + "uuid": "4a6bc7d3-5d3b-4ad8-96ae-783e17af7c32", "core": false, "unlocked_by": "matrix", "difficulty": 5, "topics": [ "loops", + "strings", + "transforming" + ] + }, + { + "slug": "armstrong-numbers", + "uuid": "77c5c7e6-265a-4f1a-9bc4-851f8f825420", + "core": false, + "unlocked_by": "series", + "difficulty": 3, + "topics": [ "math" ] }, { - "slug": "grade-school", - "uuid": "4460742c-2beb-48d7-94e6-72ff13c68c71", + "slug": "flatten-array", + "uuid": "2df8ed82-2a04-4112-a17b-7813bcdc0e84", "core": false, - "unlocked_by": "luhn", - "difficulty": 5, + "unlocked_by": "series", + "difficulty": 3, "topics": [ - "lists", - "sorting", - "structs" + "arrays", + "recursion" ] }, { @@ -417,29 +373,39 @@ ] }, { - "slug": "prime-factors", - "uuid": "a18daa31-88d3-45ba-84ca-f1d52fe23a79", + "slug": "grains", + "uuid": "22519f53-4516-43bc-915e-07d58e48f617", "core": false, - "unlocked_by": "clock", - "difficulty": 3, + "unlocked_by": "series", + "difficulty": 4, "topics": [ - "algorithms", - "integers", + "bitwise_operations", "math" ] }, { - "slug": "strain", - "uuid": "ac0966a9-822b-45be-91d9-36f6706ea76f", + "slug": "resistor-color-trio", + "uuid": "2df14b68-75c8-4984-8ae2-ecd2cb7ed1d4", "core": false, - "unlocked_by": "raindrops", - "difficulty": 2, + "unlocked_by": "series", + "difficulty": 5, "topics": [ - "arrays", - "filtering", "loops" ] }, + { + "slug": "saddle-points", + "uuid": "38bb4ac6-a5ec-4448-8b86-cdaff13a8be3", + "core": false, + "unlocked_by": "series", + "difficulty": 5, + "topics": [ + "arrays", + "integers", + "matrices", + "searching" + ] + }, { "slug": "etl", "uuid": "0d66f3db-69a4-44b9-80be-9366f8b189ec", @@ -453,201 +419,171 @@ ] }, { - "slug": "trinary", - "uuid": "f6735416-4be6-4eb8-b6b9-cb61671ce25e", - "core": false, - "unlocked_by": null, - "difficulty": 0, - "topics": null, - "deprecated": true, - "status": "deprecated" - }, - { - "slug": "beer-song", - "uuid": "50c34698-7767-42b3-962f-21c735e49787", + "slug": "nucleotide-count", + "uuid": "8ad2bffd-1d79-4e1f-8ef3-ece0214d2804", "core": false, - "unlocked_by": "scrabble-score", - "difficulty": 3, + "unlocked_by": "word-count", + "difficulty": 4, "topics": [ - "loops", - "strings", - "text_formatting" + "maps", + "parsing", + "strings" ] }, { - "slug": "bowling", - "uuid": "051f0825-8357-4ca6-b24f-40a373deac19", + "slug": "pythagorean-triplet", + "uuid": "43aad536-0e24-464c-9554-cbc2699d0543", "core": false, - "unlocked_by": "twelve-days", + "unlocked_by": "word-count", "difficulty": 5, "topics": [ "algorithms", - "arrays", - "conditionals" + "math" ] }, { - "slug": "space-age", - "uuid": "c971a2b5-ccd4-4e55-9fc7-33e991bc0676", + "slug": "collatz-conjecture", + "uuid": "af961c87-341c-4dd3-a1eb-272501b9b0e4", "core": false, - "unlocked_by": "acronym", - "difficulty": 2, + "unlocked_by": "hamming", + "difficulty": 1, "topics": [ - "floating_point_numbers", - "if_else_statements" + "conditionals", + "control_flow_loops", + "integers", + "math" ] }, { - "slug": "anagram", - "uuid": "36df18ba-580d-4982-984e-ba50eb1f8c0b", + "slug": "sieve", + "uuid": "80f9af5a-ea29-4937-9333-b4494aaf2446", "core": false, - "unlocked_by": "matrix", - "difficulty": 5, - "topics": [ - "filtering", - "parsing", - "sorting", - "strings" - ] - }, - { - "slug": "binary-search-tree", - "uuid": "0e05bfcf-17ae-4884-803a-fa1428bc1702", - "core": false, - "unlocked_by": "luhn", - "difficulty": 5, + "unlocked_by": "hamming", + "difficulty": 3, "topics": [ "algorithms", - "recursion", - "searching", - "sorting", - "structs", - "trees" + "integers", + "loops", + "math", + "sorting" ] }, { - "slug": "crypto-square", - "uuid": "86f8e33d-31b7-43e3-8ea3-2e391133704a", + "slug": "proverb", + "uuid": "3c5193ab-6471-4be2-9d24-1d2b51ad822a", "core": false, - "unlocked_by": "luhn", - "difficulty": 3, + "unlocked_by": "hamming", + "difficulty": 4, "topics": [ - "cryptography", - "filtering", - "strings", - "text_formatting", - "transforming" + "arrays", + "loops", + "strings" ] }, { - "slug": "alphametics", - "uuid": "2323a2a5-c181-4c1e-9c5f-f6b92b2de511", + "slug": "palindrome-products", + "uuid": "abd68340-91b9-48c1-8567-79822bb2165c", "core": false, - "unlocked_by": "raindrops", - "difficulty": 5, + "unlocked_by": "hamming", + "difficulty": 6, "topics": [ "algorithms", - "arrays", - "searching" + "math" ] }, { - "slug": "rail-fence-cipher", - "uuid": "64196fe5-2270-4113-a614-fbfbb6d00f2b", + "slug": "accumulate", + "uuid": "2c71fc3a-2c93-402b-b091-697b795ce3ba", "core": false, - "unlocked_by": "isogram", - "difficulty": 4, + "unlocked_by": "raindrops", + "difficulty": 1, "topics": [ - "algorithms", - "cryptography", - "loops", - "sorting", - "strings", - "text_formatting", - "transforming" + "lists" ] }, { - "slug": "nucleotide-count", - "uuid": "8ad2bffd-1d79-4e1f-8ef3-ece0214d2804", + "slug": "bob", + "uuid": "70fec82e-3038-468f-96ef-bfb48ce03ef3", "core": false, - "unlocked_by": "word-count", - "difficulty": 4, + "unlocked_by": "raindrops", + "difficulty": 2, "topics": [ - "maps", - "parsing", + "conditionals", "strings" ] }, { - "slug": "flatten-array", - "uuid": "2df8ed82-2a04-4112-a17b-7813bcdc0e84", + "slug": "strain", + "uuid": "ac0966a9-822b-45be-91d9-36f6706ea76f", "core": false, - "unlocked_by": "series", - "difficulty": 3, + "unlocked_by": "raindrops", + "difficulty": 2, "topics": [ "arrays", - "recursion" + "filtering", + "loops" ] }, { - "slug": "hexadecimal", - "uuid": "6984cc14-91f8-47a7-b7e2-4b210a5dbc5c", + "slug": "nth-prime", + "uuid": "16baef71-6234-4928-a2d4-a19eb8e110b8", "core": false, - "unlocked_by": null, - "difficulty": 0, - "topics": null, - "deprecated": true, - "status": "deprecated" + "unlocked_by": "raindrops", + "difficulty": 3, + "topics": [ + "algorithms", + "integers", + "math" + ] }, { - "slug": "say", - "uuid": "2a410923-6445-41fc-9cf3-a60209e1c1c2", + "slug": "perfect-numbers", + "uuid": "76ad732a-6e58-403b-ac65-9091d355241f", "core": false, - "unlocked_by": "twelve-days", - "difficulty": 7, + "unlocked_by": "raindrops", + "difficulty": 4, "topics": [ - "numbers", - "strings", - "text_formatting", - "transforming" + "algorithms", + "filtering", + "integers", + "math" ] }, { - "slug": "meetup", - "uuid": "8120e133-9561-4f82-8081-10c19f7f6ba3", + "slug": "alphametics", + "uuid": "2323a2a5-c181-4c1e-9c5f-f6b92b2de511", "core": false, - "unlocked_by": "twelve-days", - "difficulty": 3, + "unlocked_by": "raindrops", + "difficulty": 5, "topics": [ - "dates", - "time", - "transforming", - "type_conversion" + "algorithms", + "arrays", + "searching" ] }, { - "slug": "queen-attack", - "uuid": "2ce9b158-e730-4c86-8639-bd08af9f80f4", + "slug": "binary-search", + "uuid": "b1ba445d-4908-4922-acc0-de3a0ec92c53", "core": false, - "unlocked_by": "tournament", + "unlocked_by": "raindrops", "difficulty": 5, "topics": [ - "booleans", - "errors", - "games", - "logic" + "algorithms", + "arrays", + "searching", + "sorting" ] }, { - "slug": "palindrome-products", - "uuid": "abd68340-91b9-48c1-8567-79822bb2165c", + "slug": "two-bucket", + "uuid": "e5a2d445-437d-46a8-889b-fbcd62c70fa9", "core": false, - "unlocked_by": "hamming", - "difficulty": 6, + "unlocked_by": "raindrops", + "difficulty": 5, "topics": [ "algorithms", - "math" + "conditionals", + "searching" ] }, { @@ -662,253 +598,270 @@ ] }, { - "slug": "food-chain", - "uuid": "6f0919eb-2160-4cca-8504-286acc2ae9c8", + "slug": "all-your-base", + "uuid": "3ce4bd3e-0380-498a-8d0a-b79cf3fedc10", "core": false, - "unlocked_by": "tournament", - "difficulty": 4, + "unlocked_by": "isogram", + "difficulty": 3, "topics": [ - "conditionals", - "loops", - "recursion", - "strings", - "text_formatting" + "integers", + "math", + "transforming" ] }, { - "slug": "saddle-points", - "uuid": "38bb4ac6-a5ec-4448-8b86-cdaff13a8be3", + "slug": "scale-generator", + "uuid": "4134d491-8ec5-480b-aa61-37a02689db1f", "core": false, - "unlocked_by": "series", - "difficulty": 5, + "unlocked_by": "isogram", + "difficulty": 3, "topics": [ - "arrays", - "integers", - "matrices", - "searching" + "pattern_matching", + "strings" ] }, { - "slug": "triangle", - "uuid": "5c797eb2-155d-47ca-8f85-2ba5803f9713", + "slug": "allergies", + "uuid": "b306bdaa-438e-46a2-ba54-82cb2c0be882", "core": false, - "unlocked_by": "high-scores", - "difficulty": 3, + "unlocked_by": "isogram", + "difficulty": 4, "topics": [ - "booleans", - "conditionals", - "logic" + "bitwise_operations", + "enumeration" ] }, { - "slug": "atbash-cipher", - "uuid": "1e737640-9785-4a47-866a-46298104d891", + "slug": "rail-fence-cipher", + "uuid": "64196fe5-2270-4113-a614-fbfbb6d00f2b", "core": false, - "unlocked_by": "luhn", - "difficulty": 3, + "unlocked_by": "isogram", + "difficulty": 4, "topics": [ "algorithms", "cryptography", + "loops", + "sorting", "strings", + "text_formatting", "transforming" ] }, { - "slug": "house", - "uuid": "df5d771a-e57b-4a96-8a29-9bd4ce7f88d2", + "slug": "run-length-encoding", + "uuid": "9d6a8c89-41c1-4c4e-b24c-476ba0dfa5f9", "core": false, - "unlocked_by": "clock", + "unlocked_by": "isogram", "difficulty": 4, "topics": [ - "recursion", + "parsing", "strings", - "text_formatting" + "transforming" ] }, { - "slug": "secret-handshake", - "uuid": "c1ebad1b-d5aa-465a-b5ef-9e717ab5db9e", + "slug": "minesweeper", + "uuid": "9d6808fb-d367-4df9-a1f0-47ff83b75544", "core": false, - "unlocked_by": "scrabble-score", + "unlocked_by": "isogram", "difficulty": 5, "topics": [ "arrays", - "bitwise_operations", - "integers" + "games", + "loops", + "matrices", + "transforming" ] }, { - "slug": "proverb", - "uuid": "3c5193ab-6471-4be2-9d24-1d2b51ad822a", + "slug": "robot-simulator", + "uuid": "724e6a6e-2e6e-45a9-ab0e-0d8d50a06085", "core": false, - "unlocked_by": "hamming", - "difficulty": 4, + "unlocked_by": "isogram", + "difficulty": 6, "topics": [ - "arrays", + "concurrency", "loops", - "strings" + "sequences", + "strings", + "structs" ] }, { - "slug": "ocr-numbers", - "uuid": "dd13bb29-589c-497d-9580-3f288f353fb2", + "slug": "beer-song", + "uuid": "50c34698-7767-42b3-962f-21c735e49787", "core": false, - "unlocked_by": "twelve-days", - "difficulty": 7, + "unlocked_by": "scrabble-score", + "difficulty": 3, "topics": [ - "parsing", - "pattern_recognition" + "loops", + "strings", + "text_formatting" ] }, { - "slug": "pig-latin", - "uuid": "efc0e498-891a-4e91-a6aa-fae635573a83", + "slug": "protein-translation", + "uuid": "00c6f623-2e54-4f90-ae3f-07e493f93c7c", "core": false, - "unlocked_by": "luhn", - "difficulty": 4, + "unlocked_by": "scrabble-score", + "difficulty": 3, + "topics": [ + "filtering", + "maps", + "sequences" + ] + }, + { + "slug": "wordy", + "uuid": "cb58e4cf-e3af-469c-9f2d-02557b9f61ed", + "core": false, + "unlocked_by": "scrabble-score", + "difficulty": 3, "topics": [ "conditionals", + "integers", + "parsing", "strings", - "transforming" + "type_conversion" ] }, { - "slug": "simple-linked-list", - "uuid": "fa7b91c2-842c-42c8-bdf9-00bb3e71a7f5", + "slug": "secret-handshake", + "uuid": "c1ebad1b-d5aa-465a-b5ef-9e717ab5db9e", "core": false, - "unlocked_by": "luhn", - "difficulty": 4, + "unlocked_by": "scrabble-score", + "difficulty": 5, "topics": [ "arrays", - "loops" + "bitwise_operations", + "integers" ] }, { - "slug": "simple-cipher", - "uuid": "29c66e8a-b1b0-4bbd-be7b-9979ff51ba8f", + "slug": "atbash-cipher", + "uuid": "1e737640-9785-4a47-866a-46298104d891", "core": false, "unlocked_by": "luhn", "difficulty": 3, "topics": [ "algorithms", "cryptography", - "interfaces", "strings", "transforming" ] }, { - "slug": "wordy", - "uuid": "cb58e4cf-e3af-469c-9f2d-02557b9f61ed", + "slug": "crypto-square", + "uuid": "86f8e33d-31b7-43e3-8ea3-2e391133704a", "core": false, - "unlocked_by": "scrabble-score", + "unlocked_by": "luhn", "difficulty": 3, "topics": [ - "conditionals", - "integers", - "parsing", + "cryptography", + "filtering", "strings", - "type_conversion" + "text_formatting", + "transforming" ] }, { - "slug": "allergies", - "uuid": "b306bdaa-438e-46a2-ba54-82cb2c0be882", + "slug": "list-ops", + "uuid": "f62e8acb-8370-46e1-ad7f-a6a2644f8602", "core": false, - "unlocked_by": "isogram", - "difficulty": 4, + "unlocked_by": "luhn", + "difficulty": 3, "topics": [ - "bitwise_operations", - "enumeration" + "functional_programming", + "lists", + "recursion", + "type_conversion" ] }, { - "slug": "poker", - "uuid": "9a59ba44-34f5-410b-a1e6-9a5c47c52d9e", + "slug": "robot-name", + "uuid": "76a0fd0a-cc65-4be3-acc8-7348bb67ad5a", "core": false, - "unlocked_by": "clock", - "difficulty": 5, + "unlocked_by": "luhn", + "difficulty": 3, "topics": [ - "equality", - "games", - "parsing", - "pattern_matching", - "sequences", - "strings" + "randomness" ] }, { - "slug": "kindergarten-garden", - "uuid": "04bde625-e363-4d8b-880f-db7bf86286eb", + "slug": "simple-cipher", + "uuid": "29c66e8a-b1b0-4bbd-be7b-9979ff51ba8f", "core": false, - "unlocked_by": "clock", + "unlocked_by": "luhn", "difficulty": 3, "topics": [ - "parsing", - "records", - "searching", + "algorithms", + "cryptography", + "interfaces", "strings", - "structs" + "transforming" ] }, { - "slug": "largest-series-product", - "uuid": "7cb55328-1b11-4544-94c0-945444d9a6a4", + "slug": "dominoes", + "uuid": "705f3eb6-55a9-476c-b3f2-e9f3cb0bbe37", "core": false, - "unlocked_by": "clock", - "difficulty": 3, + "unlocked_by": "luhn", + "difficulty": 4, "topics": [ "algorithms", - "integers", - "math", - "sequences" + "arrays", + "searching" ] }, { - "slug": "pythagorean-triplet", - "uuid": "43aad536-0e24-464c-9554-cbc2699d0543", + "slug": "pig-latin", + "uuid": "efc0e498-891a-4e91-a6aa-fae635573a83", "core": false, - "unlocked_by": "word-count", - "difficulty": 5, + "unlocked_by": "luhn", + "difficulty": 4, "topics": [ - "algorithms", - "math" + "conditionals", + "strings", + "transforming" ] }, { - "slug": "scale-generator", - "uuid": "4134d491-8ec5-480b-aa61-37a02689db1f", + "slug": "simple-linked-list", + "uuid": "fa7b91c2-842c-42c8-bdf9-00bb3e71a7f5", "core": false, - "unlocked_by": "isogram", - "difficulty": 3, + "unlocked_by": "luhn", + "difficulty": 4, "topics": [ - "pattern_matching", - "strings" + "arrays", + "loops" ] }, { - "slug": "protein-translation", - "uuid": "00c6f623-2e54-4f90-ae3f-07e493f93c7c", + "slug": "binary-search-tree", + "uuid": "0e05bfcf-17ae-4884-803a-fa1428bc1702", "core": false, - "unlocked_by": "scrabble-score", - "difficulty": 3, + "unlocked_by": "luhn", + "difficulty": 5, "topics": [ - "filtering", - "maps", - "sequences" + "algorithms", + "recursion", + "searching", + "sorting", + "structs", + "trees" ] }, { - "slug": "perfect-numbers", - "uuid": "76ad732a-6e58-403b-ac65-9091d355241f", + "slug": "change", + "uuid": "dc6c3e44-1027-4d53-9653-ba06824f8bcf", "core": false, - "unlocked_by": "raindrops", - "difficulty": 4, + "unlocked_by": "luhn", + "difficulty": 5, "topics": [ "algorithms", - "filtering", - "integers", - "math" + "arrays", + "loops", + "searching" ] }, { @@ -923,182 +876,138 @@ ] }, { - "slug": "diamond", - "uuid": "c55c75fb-6140-4042-967a-39c75b7781bd", + "slug": "grade-school", + "uuid": "4460742c-2beb-48d7-94e6-72ff13c68c71", "core": false, - "unlocked_by": "twelve-days", - "difficulty": 4, + "unlocked_by": "luhn", + "difficulty": 5, "topics": [ - "algorithms", - "conditionals", - "loops", - "strings", - "text_formatting" + "lists", + "sorting", + "structs" ] }, { - "slug": "custom-set", - "uuid": "4f74b3cd-f995-4b8c-9b57-23f073261d0e", + "slug": "roman-numerals", + "uuid": "b7ca9519-c33b-418b-a4ef-858a3d4d6855", "core": false, "unlocked_by": "clock", - "difficulty": 4, + "difficulty": 2, "topics": [ - "filtering", - "loops", - "sets" + "numbers", + "transforming" ] }, { - "slug": "transpose", - "uuid": "4a6bc7d3-5d3b-4ad8-96ae-783e17af7c32", + "slug": "rotational-cipher", + "uuid": "af5ccf14-eff2-4dc6-b1db-e209cddca62a", "core": false, - "unlocked_by": "matrix", - "difficulty": 5, + "unlocked_by": "clock", + "difficulty": 2, "topics": [ - "loops", - "strings", - "transforming" + "cryptography", + "integers", + "strings" ] }, { - "slug": "pascals-triangle", - "uuid": "4ff8b056-f27d-4bdf-b7af-214448db4260", + "slug": "affine-cipher", + "uuid": "d1267415-aff5-411d-b267-49a4a2c8fda2", "core": false, - "unlocked_by": "tournament", - "difficulty": 4, + "unlocked_by": "clock", + "difficulty": 3, "topics": [ - "algorithms", - "arrays", + "cryptography", "math", - "recursion" + "strings" ] }, { - "slug": "linked-list", - "uuid": "92c9aafc-791d-4aaf-a136-9bee14f6ff95", + "slug": "kindergarten-garden", + "uuid": "04bde625-e363-4d8b-880f-db7bf86286eb", "core": false, "unlocked_by": "clock", - "difficulty": 4, + "difficulty": 3, "topics": [ - "data_structure", - "pointer" + "parsing", + "records", + "searching", + "strings", + "structs" ] }, { - "slug": "binary-search", - "uuid": "b1ba445d-4908-4922-acc0-de3a0ec92c53", + "slug": "largest-series-product", + "uuid": "7cb55328-1b11-4544-94c0-945444d9a6a4", "core": false, - "unlocked_by": "raindrops", - "difficulty": 5, + "unlocked_by": "clock", + "difficulty": 3, "topics": [ "algorithms", - "arrays", - "searching", - "sorting" + "integers", + "math", + "sequences" ] }, { - "slug": "minesweeper", - "uuid": "9d6808fb-d367-4df9-a1f0-47ff83b75544", + "slug": "prime-factors", + "uuid": "a18daa31-88d3-45ba-84ca-f1d52fe23a79", "core": false, - "unlocked_by": "isogram", - "difficulty": 5, - "topics": [ - "arrays", - "games", - "loops", - "matrices", - "transforming" - ] - }, - { - "slug": "robot-simulator", - "uuid": "724e6a6e-2e6e-45a9-ab0e-0d8d50a06085", - "core": false, - "unlocked_by": "isogram", - "difficulty": 6, - "topics": [ - "concurrency", - "loops", - "sequences", - "strings", - "structs" - ] - }, - { - "slug": "all-your-base", - "uuid": "3ce4bd3e-0380-498a-8d0a-b79cf3fedc10", - "core": false, - "unlocked_by": "isogram", - "difficulty": 3, + "unlocked_by": "clock", + "difficulty": 3, "topics": [ + "algorithms", "integers", - "math", - "transforming" - ] - }, - { - "slug": "connect", - "uuid": "538a6768-bae5-437c-9cdf-765d73a79643", - "core": false, - "unlocked_by": "tournament", - "difficulty": 9, - "topics": [ - "arrays", - "games", - "graphs", - "loops", - "searching" + "math" ] }, { - "slug": "change", - "uuid": "dc6c3e44-1027-4d53-9653-ba06824f8bcf", + "slug": "custom-set", + "uuid": "4f74b3cd-f995-4b8c-9b57-23f073261d0e", "core": false, - "unlocked_by": "luhn", - "difficulty": 5, + "unlocked_by": "clock", + "difficulty": 4, "topics": [ - "algorithms", - "arrays", + "filtering", "loops", - "searching" + "sets" ] }, { - "slug": "collatz-conjecture", - "uuid": "af961c87-341c-4dd3-a1eb-272501b9b0e4", + "slug": "house", + "uuid": "df5d771a-e57b-4a96-8a29-9bd4ce7f88d2", "core": false, - "unlocked_by": "hamming", - "difficulty": 1, + "unlocked_by": "clock", + "difficulty": 4, "topics": [ - "conditionals", - "control_flow_loops", - "integers", - "math" + "recursion", + "strings", + "text_formatting" ] }, { - "slug": "book-store", - "uuid": "0ec96460-08be-49a0-973a-4336f21b763c", + "slug": "linked-list", + "uuid": "92c9aafc-791d-4aaf-a136-9bee14f6ff95", "core": false, - "unlocked_by": "tournament", - "difficulty": 8, + "unlocked_by": "clock", + "difficulty": 4, "topics": [ - "algorithms", - "floating_point_numbers", - "integers", - "lists" + "data_structure", + "pointer" ] }, { - "slug": "rotational-cipher", - "uuid": "af5ccf14-eff2-4dc6-b1db-e209cddca62a", + "slug": "poker", + "uuid": "9a59ba44-34f5-410b-a1e6-9a5c47c52d9e", "core": false, "unlocked_by": "clock", - "difficulty": 2, + "difficulty": 5, "topics": [ - "cryptography", - "integers", + "equality", + "games", + "parsing", + "pattern_matching", + "sequences", "strings" ] }, @@ -1113,83 +1022,77 @@ ] }, { - "slug": "dominoes", - "uuid": "705f3eb6-55a9-476c-b3f2-e9f3cb0bbe37", - "core": false, - "unlocked_by": "luhn", - "difficulty": 4, - "topics": [ - "algorithms", - "arrays", - "searching" - ] - }, - { - "slug": "two-bucket", - "uuid": "e5a2d445-437d-46a8-889b-fbcd62c70fa9", + "slug": "complex-numbers", + "uuid": "d75bd7c0-52c5-44f2-a046-f63cb332425f", "core": false, - "unlocked_by": "raindrops", - "difficulty": 5, + "unlocked_by": "twelve-days", + "difficulty": 3, "topics": [ - "algorithms", - "conditionals", - "searching" + "math" ] }, { - "slug": "list-ops", - "uuid": "f62e8acb-8370-46e1-ad7f-a6a2644f8602", + "slug": "meetup", + "uuid": "8120e133-9561-4f82-8081-10c19f7f6ba3", "core": false, - "unlocked_by": "luhn", + "unlocked_by": "twelve-days", "difficulty": 3, "topics": [ - "functional_programming", - "lists", - "recursion", + "dates", + "time", + "transforming", "type_conversion" ] }, { - "slug": "octal", - "uuid": "cae4e000-3aac-41f7-b727-f9cce12d058d", + "slug": "diamond", + "uuid": "c55c75fb-6140-4042-967a-39c75b7781bd", "core": false, - "unlocked_by": null, - "difficulty": 0, - "topics": null, - "deprecated": true, - "status": "deprecated" + "unlocked_by": "twelve-days", + "difficulty": 4, + "topics": [ + "algorithms", + "conditionals", + "loops", + "strings", + "text_formatting" + ] }, { - "slug": "affine-cipher", - "uuid": "d1267415-aff5-411d-b267-49a4a2c8fda2", + "slug": "bowling", + "uuid": "051f0825-8357-4ca6-b24f-40a373deac19", "core": false, - "unlocked_by": "clock", - "difficulty": 3, + "unlocked_by": "twelve-days", + "difficulty": 5, "topics": [ - "cryptography", - "math", - "strings" + "algorithms", + "arrays", + "conditionals" ] }, { - "slug": "complex-numbers", - "uuid": "d75bd7c0-52c5-44f2-a046-f63cb332425f", + "slug": "ocr-numbers", + "uuid": "dd13bb29-589c-497d-9580-3f288f353fb2", "core": false, "unlocked_by": "twelve-days", - "difficulty": 3, + "difficulty": 7, "topics": [ - "math" + "parsing", + "pattern_recognition" ] }, { - "slug": "point-mutations", - "uuid": "89bd3d71-000f-4cd9-9a84-ad1b22ddbd33", + "slug": "say", + "uuid": "2a410923-6445-41fc-9cf3-a60209e1c1c2", "core": false, - "unlocked_by": null, - "difficulty": 0, - "topics": null, - "deprecated": true, - "status": "deprecated" + "unlocked_by": "twelve-days", + "difficulty": 7, + "topics": [ + "numbers", + "strings", + "text_formatting", + "transforming" + ] }, { "slug": "zipper", @@ -1217,36 +1120,122 @@ ] }, { - "slug": "resistor-color", - "uuid": "685634dd-0b38-40bc-b0ad-e8aa2904035f", + "slug": "food-chain", + "uuid": "6f0919eb-2160-4cca-8504-286acc2ae9c8", "core": false, - "unlocked_by": "hello-world", - "difficulty": 1, + "unlocked_by": "tournament", + "difficulty": 4, "topics": [ - "arrays" + "conditionals", + "loops", + "recursion", + "strings", + "text_formatting" ] }, { - "slug": "resistor-color-trio", - "uuid": "2df14b68-75c8-4984-8ae2-ecd2cb7ed1d4", + "slug": "pascals-triangle", + "uuid": "4ff8b056-f27d-4bdf-b7af-214448db4260", "core": false, - "unlocked_by": "series", + "unlocked_by": "tournament", + "difficulty": 4, + "topics": [ + "algorithms", + "arrays", + "math", + "recursion" + ] + }, + { + "slug": "queen-attack", + "uuid": "2ce9b158-e730-4c86-8639-bd08af9f80f4", + "core": false, + "unlocked_by": "tournament", "difficulty": 5, "topics": [ - "loops" + "booleans", + "errors", + "games", + "logic" ] }, { - "slug": "darts", - "uuid": "15b73808-78a4-4854-b7cf-82a478107024", + "slug": "book-store", + "uuid": "0ec96460-08be-49a0-973a-4336f21b763c", "core": false, - "unlocked_by": null, - "difficulty": 3, + "unlocked_by": "tournament", + "difficulty": 8, "topics": [ - "math", - "geometry" + "algorithms", + "floating_point_numbers", + "integers", + "lists" + ] + }, + { + "slug": "connect", + "uuid": "538a6768-bae5-437c-9cdf-765d73a79643", + "core": false, + "unlocked_by": "tournament", + "difficulty": 9, + "topics": [ + "arrays", + "games", + "graphs", + "loops", + "searching" ] }, + { + "slug": "binary", + "uuid": "43bc27ed-d2fa-4173-8665-4459b71c9a3a", + "core": false, + "unlocked_by": null, + "difficulty": 0, + "topics": null, + "deprecated": true, + "status": "deprecated" + }, + { + "slug": "hexadecimal", + "uuid": "6984cc14-91f8-47a7-b7e2-4b210a5dbc5c", + "core": false, + "unlocked_by": null, + "difficulty": 0, + "topics": null, + "deprecated": true, + "status": "deprecated" + }, + { + "slug": "octal", + "uuid": "cae4e000-3aac-41f7-b727-f9cce12d058d", + "core": false, + "unlocked_by": null, + "difficulty": 0, + "topics": null, + "deprecated": true, + "status": "deprecated" + }, + { + "slug": "point-mutations", + "uuid": "89bd3d71-000f-4cd9-9a84-ad1b22ddbd33", + "core": false, + "unlocked_by": null, + "difficulty": 0, + "topics": null, + "deprecated": true, + "status": "deprecated" + }, + { + "slug": "trinary", + "uuid": "f6735416-4be6-4eb8-b6b9-cb61671ce25e", + "core": false, + "unlocked_by": null, + "difficulty": 0, + "topics": null, + "deprecated": true, + "status": "deprecated" + }, { "slug": "microwave", "uuid": "b960d0fe-a07f-11ea-bb37-0242ac130002", @@ -1258,6 +1247,17 @@ "strings", "interpolation" ] + }, + { + "slug": "darts", + "uuid": "15b73808-78a4-4854-b7cf-82a478107024", + "core": false, + "unlocked_by": null, + "difficulty": 3, + "topics": [ + "math", + "geometry" + ] } ] } From fb432db81e936a61e52d1acbb62fec6b94f0b548 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:45 +0100 Subject: [PATCH 089/102] [v3] Remove deprecated properties from practice exercises in config.json --- config.json | 212 ---------------------------------------------------- 1 file changed, 212 deletions(-) diff --git a/config.json b/config.json index 316ee8403e..98625a5589 100644 --- a/config.json +++ b/config.json @@ -20,9 +20,6 @@ { "slug": "hello-world", "uuid": "4fe19484-4414-471b-a106-73c776c61388", - "core": true, - "auto_approve": true, - "unlocked_by": null, "difficulty": 1, "topics": [ "strings" @@ -31,8 +28,6 @@ { "slug": "two-fer", "uuid": "1304b188-6d08-4361-be40-c6b1b88e5e54", - "core": true, - "unlocked_by": null, "difficulty": 1, "topics": [ "conditionals", @@ -42,8 +37,6 @@ { "slug": "resistor-color-duo", "uuid": "57b0c57e-26a5-4ccf-aaf2-2fefddd918c1", - "core": true, - "unlocked_by": null, "difficulty": 1, "topics": [ "array", @@ -53,8 +46,6 @@ { "slug": "acronym", "uuid": "74468206-68a2-4efb-8caa-782634674c7f", - "core": true, - "unlocked_by": null, "difficulty": 1, "topics": [ "regular_expressions", @@ -65,8 +56,6 @@ { "slug": "high-scores", "uuid": "9124339c-94fb-46eb-aad2-25944214799d", - "core": true, - "unlocked_by": null, "difficulty": 2, "topics": [ "arrays" @@ -75,8 +64,6 @@ { "slug": "matrix", "uuid": "3de21c18-a533-4150-8a73-49df8fcb8c61", - "core": true, - "unlocked_by": null, "difficulty": 4, "topics": [ "arrays", @@ -89,8 +76,6 @@ { "slug": "series", "uuid": "2de036e4-576d-47fc-bb03-4ed1612e79da", - "core": true, - "unlocked_by": null, "difficulty": 3, "topics": [ "arrays", @@ -101,8 +86,6 @@ { "slug": "word-count", "uuid": "e9d29769-8d4d-4159-8d6f-762db5339707", - "core": true, - "unlocked_by": null, "difficulty": 3, "topics": [ "enumerable", @@ -113,8 +96,6 @@ { "slug": "hamming", "uuid": "d33dec8a-e2b4-40bc-8be9-3f49de084d43", - "core": true, - "unlocked_by": null, "difficulty": 1, "topics": [ "equality", @@ -125,8 +106,6 @@ { "slug": "raindrops", "uuid": "efad2cea-1e0b-4fb8-a452-a8e91be73638", - "core": true, - "unlocked_by": null, "difficulty": 1, "topics": [ "conditionals", @@ -137,8 +116,6 @@ { "slug": "isogram", "uuid": "a79eb8cd-d2db-48f5-a7dc-055039dcee62", - "core": true, - "unlocked_by": null, "difficulty": 2, "topics": [ "regular_expressions", @@ -149,8 +126,6 @@ { "slug": "scrabble-score", "uuid": "d934ebce-9ac3-4a41-bcb8-d70480170438", - "core": true, - "unlocked_by": null, "difficulty": 2, "topics": [ "loops", @@ -161,8 +136,6 @@ { "slug": "luhn", "uuid": "bee97539-b8c1-460e-aa14-9336008df2b6", - "core": true, - "unlocked_by": null, "difficulty": 2, "topics": [ "algorithms", @@ -173,8 +146,6 @@ { "slug": "clock", "uuid": "f95ebf09-0f32-4e60-867d-60cb81dd9a62", - "core": true, - "unlocked_by": null, "difficulty": 3, "topics": [ "equality", @@ -185,8 +156,6 @@ { "slug": "twelve-days", "uuid": "eeb64dda-b79f-4920-8fa3-04810e8d37ab", - "core": true, - "unlocked_by": null, "difficulty": 4, "topics": [ "algorithms", @@ -199,8 +168,6 @@ { "slug": "tournament", "uuid": "486becee-9d85-4139-ab89-db254d385ade", - "core": true, - "unlocked_by": null, "difficulty": 3, "topics": [ "integers", @@ -215,8 +182,6 @@ { "slug": "gigasecond", "uuid": "0fb594a1-193b-4ccf-8de2-eb6a81708b29", - "core": false, - "unlocked_by": "hello-world", "difficulty": 1, "topics": [ "time" @@ -225,8 +190,6 @@ { "slug": "resistor-color", "uuid": "685634dd-0b38-40bc-b0ad-e8aa2904035f", - "core": false, - "unlocked_by": "hello-world", "difficulty": 1, "topics": [ "arrays" @@ -235,8 +198,6 @@ { "slug": "rna-transcription", "uuid": "41f66d2a-1883-4a2c-875f-663c46fa88aa", - "core": false, - "unlocked_by": "two-fer", "difficulty": 2, "topics": [ "maps", @@ -246,8 +207,6 @@ { "slug": "leap", "uuid": "06eaa2dd-dc80-4d38-b10d-11174183b0b6", - "core": false, - "unlocked_by": "resistor-color-duo", "difficulty": 1, "topics": [ "booleans", @@ -259,8 +218,6 @@ { "slug": "pangram", "uuid": "fcf07149-b2cb-4042-90e6-fb3350e0fdf6", - "core": false, - "unlocked_by": "acronym", "difficulty": 2, "topics": [ "loops", @@ -270,8 +227,6 @@ { "slug": "space-age", "uuid": "c971a2b5-ccd4-4e55-9fc7-33e991bc0676", - "core": false, - "unlocked_by": "acronym", "difficulty": 2, "topics": [ "floating_point_numbers", @@ -281,8 +236,6 @@ { "slug": "triangle", "uuid": "5c797eb2-155d-47ca-8f85-2ba5803f9713", - "core": false, - "unlocked_by": "high-scores", "difficulty": 3, "topics": [ "booleans", @@ -293,8 +246,6 @@ { "slug": "difference-of-squares", "uuid": "f1e4ee0c-8718-43f2-90a5-fb1e915288da", - "core": false, - "unlocked_by": "matrix", "difficulty": 2, "topics": [ "algorithms", @@ -304,8 +255,6 @@ { "slug": "anagram", "uuid": "36df18ba-580d-4982-984e-ba50eb1f8c0b", - "core": false, - "unlocked_by": "matrix", "difficulty": 5, "topics": [ "filtering", @@ -317,8 +266,6 @@ { "slug": "sum-of-multiples", "uuid": "4fc25295-5d6a-4d13-9b87-064167d8980e", - "core": false, - "unlocked_by": "matrix", "difficulty": 5, "topics": [ "loops", @@ -328,8 +275,6 @@ { "slug": "transpose", "uuid": "4a6bc7d3-5d3b-4ad8-96ae-783e17af7c32", - "core": false, - "unlocked_by": "matrix", "difficulty": 5, "topics": [ "loops", @@ -340,8 +285,6 @@ { "slug": "armstrong-numbers", "uuid": "77c5c7e6-265a-4f1a-9bc4-851f8f825420", - "core": false, - "unlocked_by": "series", "difficulty": 3, "topics": [ "math" @@ -350,8 +293,6 @@ { "slug": "flatten-array", "uuid": "2df8ed82-2a04-4112-a17b-7813bcdc0e84", - "core": false, - "unlocked_by": "series", "difficulty": 3, "topics": [ "arrays", @@ -361,8 +302,6 @@ { "slug": "phone-number", "uuid": "b68665d5-14ef-4351-ac4a-c28a80c27b3d", - "core": false, - "unlocked_by": "series", "difficulty": 3, "topics": [ "conditionals", @@ -375,8 +314,6 @@ { "slug": "grains", "uuid": "22519f53-4516-43bc-915e-07d58e48f617", - "core": false, - "unlocked_by": "series", "difficulty": 4, "topics": [ "bitwise_operations", @@ -386,8 +323,6 @@ { "slug": "resistor-color-trio", "uuid": "2df14b68-75c8-4984-8ae2-ecd2cb7ed1d4", - "core": false, - "unlocked_by": "series", "difficulty": 5, "topics": [ "loops" @@ -396,8 +331,6 @@ { "slug": "saddle-points", "uuid": "38bb4ac6-a5ec-4448-8b86-cdaff13a8be3", - "core": false, - "unlocked_by": "series", "difficulty": 5, "topics": [ "arrays", @@ -409,8 +342,6 @@ { "slug": "etl", "uuid": "0d66f3db-69a4-44b9-80be-9366f8b189ec", - "core": false, - "unlocked_by": "word-count", "difficulty": 4, "topics": [ "loops", @@ -421,8 +352,6 @@ { "slug": "nucleotide-count", "uuid": "8ad2bffd-1d79-4e1f-8ef3-ece0214d2804", - "core": false, - "unlocked_by": "word-count", "difficulty": 4, "topics": [ "maps", @@ -433,8 +362,6 @@ { "slug": "pythagorean-triplet", "uuid": "43aad536-0e24-464c-9554-cbc2699d0543", - "core": false, - "unlocked_by": "word-count", "difficulty": 5, "topics": [ "algorithms", @@ -444,8 +371,6 @@ { "slug": "collatz-conjecture", "uuid": "af961c87-341c-4dd3-a1eb-272501b9b0e4", - "core": false, - "unlocked_by": "hamming", "difficulty": 1, "topics": [ "conditionals", @@ -457,8 +382,6 @@ { "slug": "sieve", "uuid": "80f9af5a-ea29-4937-9333-b4494aaf2446", - "core": false, - "unlocked_by": "hamming", "difficulty": 3, "topics": [ "algorithms", @@ -471,8 +394,6 @@ { "slug": "proverb", "uuid": "3c5193ab-6471-4be2-9d24-1d2b51ad822a", - "core": false, - "unlocked_by": "hamming", "difficulty": 4, "topics": [ "arrays", @@ -483,8 +404,6 @@ { "slug": "palindrome-products", "uuid": "abd68340-91b9-48c1-8567-79822bb2165c", - "core": false, - "unlocked_by": "hamming", "difficulty": 6, "topics": [ "algorithms", @@ -494,8 +413,6 @@ { "slug": "accumulate", "uuid": "2c71fc3a-2c93-402b-b091-697b795ce3ba", - "core": false, - "unlocked_by": "raindrops", "difficulty": 1, "topics": [ "lists" @@ -504,8 +421,6 @@ { "slug": "bob", "uuid": "70fec82e-3038-468f-96ef-bfb48ce03ef3", - "core": false, - "unlocked_by": "raindrops", "difficulty": 2, "topics": [ "conditionals", @@ -515,8 +430,6 @@ { "slug": "strain", "uuid": "ac0966a9-822b-45be-91d9-36f6706ea76f", - "core": false, - "unlocked_by": "raindrops", "difficulty": 2, "topics": [ "arrays", @@ -527,8 +440,6 @@ { "slug": "nth-prime", "uuid": "16baef71-6234-4928-a2d4-a19eb8e110b8", - "core": false, - "unlocked_by": "raindrops", "difficulty": 3, "topics": [ "algorithms", @@ -539,8 +450,6 @@ { "slug": "perfect-numbers", "uuid": "76ad732a-6e58-403b-ac65-9091d355241f", - "core": false, - "unlocked_by": "raindrops", "difficulty": 4, "topics": [ "algorithms", @@ -552,8 +461,6 @@ { "slug": "alphametics", "uuid": "2323a2a5-c181-4c1e-9c5f-f6b92b2de511", - "core": false, - "unlocked_by": "raindrops", "difficulty": 5, "topics": [ "algorithms", @@ -564,8 +471,6 @@ { "slug": "binary-search", "uuid": "b1ba445d-4908-4922-acc0-de3a0ec92c53", - "core": false, - "unlocked_by": "raindrops", "difficulty": 5, "topics": [ "algorithms", @@ -577,8 +482,6 @@ { "slug": "two-bucket", "uuid": "e5a2d445-437d-46a8-889b-fbcd62c70fa9", - "core": false, - "unlocked_by": "raindrops", "difficulty": 5, "topics": [ "algorithms", @@ -589,8 +492,6 @@ { "slug": "matching-brackets", "uuid": "26f6e297-7980-4472-8ce7-157b62b0ff40", - "core": false, - "unlocked_by": "raindrops", "difficulty": 7, "topics": [ "parsing", @@ -600,8 +501,6 @@ { "slug": "all-your-base", "uuid": "3ce4bd3e-0380-498a-8d0a-b79cf3fedc10", - "core": false, - "unlocked_by": "isogram", "difficulty": 3, "topics": [ "integers", @@ -612,8 +511,6 @@ { "slug": "scale-generator", "uuid": "4134d491-8ec5-480b-aa61-37a02689db1f", - "core": false, - "unlocked_by": "isogram", "difficulty": 3, "topics": [ "pattern_matching", @@ -623,8 +520,6 @@ { "slug": "allergies", "uuid": "b306bdaa-438e-46a2-ba54-82cb2c0be882", - "core": false, - "unlocked_by": "isogram", "difficulty": 4, "topics": [ "bitwise_operations", @@ -634,8 +529,6 @@ { "slug": "rail-fence-cipher", "uuid": "64196fe5-2270-4113-a614-fbfbb6d00f2b", - "core": false, - "unlocked_by": "isogram", "difficulty": 4, "topics": [ "algorithms", @@ -650,8 +543,6 @@ { "slug": "run-length-encoding", "uuid": "9d6a8c89-41c1-4c4e-b24c-476ba0dfa5f9", - "core": false, - "unlocked_by": "isogram", "difficulty": 4, "topics": [ "parsing", @@ -662,8 +553,6 @@ { "slug": "minesweeper", "uuid": "9d6808fb-d367-4df9-a1f0-47ff83b75544", - "core": false, - "unlocked_by": "isogram", "difficulty": 5, "topics": [ "arrays", @@ -676,8 +565,6 @@ { "slug": "robot-simulator", "uuid": "724e6a6e-2e6e-45a9-ab0e-0d8d50a06085", - "core": false, - "unlocked_by": "isogram", "difficulty": 6, "topics": [ "concurrency", @@ -690,8 +577,6 @@ { "slug": "beer-song", "uuid": "50c34698-7767-42b3-962f-21c735e49787", - "core": false, - "unlocked_by": "scrabble-score", "difficulty": 3, "topics": [ "loops", @@ -702,8 +587,6 @@ { "slug": "protein-translation", "uuid": "00c6f623-2e54-4f90-ae3f-07e493f93c7c", - "core": false, - "unlocked_by": "scrabble-score", "difficulty": 3, "topics": [ "filtering", @@ -714,8 +597,6 @@ { "slug": "wordy", "uuid": "cb58e4cf-e3af-469c-9f2d-02557b9f61ed", - "core": false, - "unlocked_by": "scrabble-score", "difficulty": 3, "topics": [ "conditionals", @@ -728,8 +609,6 @@ { "slug": "secret-handshake", "uuid": "c1ebad1b-d5aa-465a-b5ef-9e717ab5db9e", - "core": false, - "unlocked_by": "scrabble-score", "difficulty": 5, "topics": [ "arrays", @@ -740,8 +619,6 @@ { "slug": "atbash-cipher", "uuid": "1e737640-9785-4a47-866a-46298104d891", - "core": false, - "unlocked_by": "luhn", "difficulty": 3, "topics": [ "algorithms", @@ -753,8 +630,6 @@ { "slug": "crypto-square", "uuid": "86f8e33d-31b7-43e3-8ea3-2e391133704a", - "core": false, - "unlocked_by": "luhn", "difficulty": 3, "topics": [ "cryptography", @@ -767,8 +642,6 @@ { "slug": "list-ops", "uuid": "f62e8acb-8370-46e1-ad7f-a6a2644f8602", - "core": false, - "unlocked_by": "luhn", "difficulty": 3, "topics": [ "functional_programming", @@ -780,8 +653,6 @@ { "slug": "robot-name", "uuid": "76a0fd0a-cc65-4be3-acc8-7348bb67ad5a", - "core": false, - "unlocked_by": "luhn", "difficulty": 3, "topics": [ "randomness" @@ -790,8 +661,6 @@ { "slug": "simple-cipher", "uuid": "29c66e8a-b1b0-4bbd-be7b-9979ff51ba8f", - "core": false, - "unlocked_by": "luhn", "difficulty": 3, "topics": [ "algorithms", @@ -804,8 +673,6 @@ { "slug": "dominoes", "uuid": "705f3eb6-55a9-476c-b3f2-e9f3cb0bbe37", - "core": false, - "unlocked_by": "luhn", "difficulty": 4, "topics": [ "algorithms", @@ -816,8 +683,6 @@ { "slug": "pig-latin", "uuid": "efc0e498-891a-4e91-a6aa-fae635573a83", - "core": false, - "unlocked_by": "luhn", "difficulty": 4, "topics": [ "conditionals", @@ -828,8 +693,6 @@ { "slug": "simple-linked-list", "uuid": "fa7b91c2-842c-42c8-bdf9-00bb3e71a7f5", - "core": false, - "unlocked_by": "luhn", "difficulty": 4, "topics": [ "arrays", @@ -839,8 +702,6 @@ { "slug": "binary-search-tree", "uuid": "0e05bfcf-17ae-4884-803a-fa1428bc1702", - "core": false, - "unlocked_by": "luhn", "difficulty": 5, "topics": [ "algorithms", @@ -854,8 +715,6 @@ { "slug": "change", "uuid": "dc6c3e44-1027-4d53-9653-ba06824f8bcf", - "core": false, - "unlocked_by": "luhn", "difficulty": 5, "topics": [ "algorithms", @@ -867,8 +726,6 @@ { "slug": "circular-buffer", "uuid": "f3419fe3-a5f5-4bc9-bc40-49f450b8981e", - "core": false, - "unlocked_by": "luhn", "difficulty": 5, "topics": [ "queues", @@ -878,8 +735,6 @@ { "slug": "grade-school", "uuid": "4460742c-2beb-48d7-94e6-72ff13c68c71", - "core": false, - "unlocked_by": "luhn", "difficulty": 5, "topics": [ "lists", @@ -890,8 +745,6 @@ { "slug": "roman-numerals", "uuid": "b7ca9519-c33b-418b-a4ef-858a3d4d6855", - "core": false, - "unlocked_by": "clock", "difficulty": 2, "topics": [ "numbers", @@ -901,8 +754,6 @@ { "slug": "rotational-cipher", "uuid": "af5ccf14-eff2-4dc6-b1db-e209cddca62a", - "core": false, - "unlocked_by": "clock", "difficulty": 2, "topics": [ "cryptography", @@ -913,8 +764,6 @@ { "slug": "affine-cipher", "uuid": "d1267415-aff5-411d-b267-49a4a2c8fda2", - "core": false, - "unlocked_by": "clock", "difficulty": 3, "topics": [ "cryptography", @@ -925,8 +774,6 @@ { "slug": "kindergarten-garden", "uuid": "04bde625-e363-4d8b-880f-db7bf86286eb", - "core": false, - "unlocked_by": "clock", "difficulty": 3, "topics": [ "parsing", @@ -939,8 +786,6 @@ { "slug": "largest-series-product", "uuid": "7cb55328-1b11-4544-94c0-945444d9a6a4", - "core": false, - "unlocked_by": "clock", "difficulty": 3, "topics": [ "algorithms", @@ -952,8 +797,6 @@ { "slug": "prime-factors", "uuid": "a18daa31-88d3-45ba-84ca-f1d52fe23a79", - "core": false, - "unlocked_by": "clock", "difficulty": 3, "topics": [ "algorithms", @@ -964,8 +807,6 @@ { "slug": "custom-set", "uuid": "4f74b3cd-f995-4b8c-9b57-23f073261d0e", - "core": false, - "unlocked_by": "clock", "difficulty": 4, "topics": [ "filtering", @@ -976,8 +817,6 @@ { "slug": "house", "uuid": "df5d771a-e57b-4a96-8a29-9bd4ce7f88d2", - "core": false, - "unlocked_by": "clock", "difficulty": 4, "topics": [ "recursion", @@ -988,8 +827,6 @@ { "slug": "linked-list", "uuid": "92c9aafc-791d-4aaf-a136-9bee14f6ff95", - "core": false, - "unlocked_by": "clock", "difficulty": 4, "topics": [ "data_structure", @@ -999,8 +836,6 @@ { "slug": "poker", "uuid": "9a59ba44-34f5-410b-a1e6-9a5c47c52d9e", - "core": false, - "unlocked_by": "clock", "difficulty": 5, "topics": [ "equality", @@ -1014,8 +849,6 @@ { "slug": "isbn-verifier", "uuid": "a0aac827-8f7a-4065-9d05-a57009f5668d", - "core": false, - "unlocked_by": "twelve-days", "difficulty": 2, "topics": [ "arrays" @@ -1024,8 +857,6 @@ { "slug": "complex-numbers", "uuid": "d75bd7c0-52c5-44f2-a046-f63cb332425f", - "core": false, - "unlocked_by": "twelve-days", "difficulty": 3, "topics": [ "math" @@ -1034,8 +865,6 @@ { "slug": "meetup", "uuid": "8120e133-9561-4f82-8081-10c19f7f6ba3", - "core": false, - "unlocked_by": "twelve-days", "difficulty": 3, "topics": [ "dates", @@ -1047,8 +876,6 @@ { "slug": "diamond", "uuid": "c55c75fb-6140-4042-967a-39c75b7781bd", - "core": false, - "unlocked_by": "twelve-days", "difficulty": 4, "topics": [ "algorithms", @@ -1061,8 +888,6 @@ { "slug": "bowling", "uuid": "051f0825-8357-4ca6-b24f-40a373deac19", - "core": false, - "unlocked_by": "twelve-days", "difficulty": 5, "topics": [ "algorithms", @@ -1073,8 +898,6 @@ { "slug": "ocr-numbers", "uuid": "dd13bb29-589c-497d-9580-3f288f353fb2", - "core": false, - "unlocked_by": "twelve-days", "difficulty": 7, "topics": [ "parsing", @@ -1084,8 +907,6 @@ { "slug": "say", "uuid": "2a410923-6445-41fc-9cf3-a60209e1c1c2", - "core": false, - "unlocked_by": "twelve-days", "difficulty": 7, "topics": [ "numbers", @@ -1097,8 +918,6 @@ { "slug": "zipper", "uuid": "239b8e79-2983-4ce0-9dda-9bb999e79d11", - "core": false, - "unlocked_by": "twelve-days", "difficulty": 7, "topics": [ "data_structures" @@ -1107,8 +926,6 @@ { "slug": "grep", "uuid": "99485900-5d16-4848-af1c-2f1a62ad35ab", - "core": false, - "unlocked_by": "twelve-days", "difficulty": 8, "topics": [ "files", @@ -1122,8 +939,6 @@ { "slug": "food-chain", "uuid": "6f0919eb-2160-4cca-8504-286acc2ae9c8", - "core": false, - "unlocked_by": "tournament", "difficulty": 4, "topics": [ "conditionals", @@ -1136,8 +951,6 @@ { "slug": "pascals-triangle", "uuid": "4ff8b056-f27d-4bdf-b7af-214448db4260", - "core": false, - "unlocked_by": "tournament", "difficulty": 4, "topics": [ "algorithms", @@ -1149,8 +962,6 @@ { "slug": "queen-attack", "uuid": "2ce9b158-e730-4c86-8639-bd08af9f80f4", - "core": false, - "unlocked_by": "tournament", "difficulty": 5, "topics": [ "booleans", @@ -1162,8 +973,6 @@ { "slug": "book-store", "uuid": "0ec96460-08be-49a0-973a-4336f21b763c", - "core": false, - "unlocked_by": "tournament", "difficulty": 8, "topics": [ "algorithms", @@ -1175,8 +984,6 @@ { "slug": "connect", "uuid": "538a6768-bae5-437c-9cdf-765d73a79643", - "core": false, - "unlocked_by": "tournament", "difficulty": 9, "topics": [ "arrays", @@ -1189,58 +996,41 @@ { "slug": "binary", "uuid": "43bc27ed-d2fa-4173-8665-4459b71c9a3a", - "core": false, - "unlocked_by": null, "difficulty": 0, "topics": null, - "deprecated": true, "status": "deprecated" }, { "slug": "hexadecimal", "uuid": "6984cc14-91f8-47a7-b7e2-4b210a5dbc5c", - "core": false, - "unlocked_by": null, "difficulty": 0, "topics": null, - "deprecated": true, "status": "deprecated" }, { "slug": "octal", "uuid": "cae4e000-3aac-41f7-b727-f9cce12d058d", - "core": false, - "unlocked_by": null, "difficulty": 0, "topics": null, - "deprecated": true, "status": "deprecated" }, { "slug": "point-mutations", "uuid": "89bd3d71-000f-4cd9-9a84-ad1b22ddbd33", - "core": false, - "unlocked_by": null, "difficulty": 0, "topics": null, - "deprecated": true, "status": "deprecated" }, { "slug": "trinary", "uuid": "f6735416-4be6-4eb8-b6b9-cb61671ce25e", - "core": false, - "unlocked_by": null, "difficulty": 0, "topics": null, - "deprecated": true, "status": "deprecated" }, { "slug": "microwave", "uuid": "b960d0fe-a07f-11ea-bb37-0242ac130002", - "core": false, - "unlocked_by": null, "difficulty": 2, "topics": [ "math", @@ -1251,8 +1041,6 @@ { "slug": "darts", "uuid": "15b73808-78a4-4854-b7cf-82a478107024", - "core": false, - "unlocked_by": null, "difficulty": 3, "topics": [ "math", From eacfe1d61b3cc9e3c75ed952bed039e51469f561 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:45 +0100 Subject: [PATCH 090/102] [v3] Add name property to practice exercises in config.json --- config.json | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/config.json b/config.json index 98625a5589..4d731917b8 100644 --- a/config.json +++ b/config.json @@ -19,6 +19,7 @@ "exercises": [ { "slug": "hello-world", + "name": "Hello World", "uuid": "4fe19484-4414-471b-a106-73c776c61388", "difficulty": 1, "topics": [ @@ -27,6 +28,7 @@ }, { "slug": "two-fer", + "name": "Two Fer", "uuid": "1304b188-6d08-4361-be40-c6b1b88e5e54", "difficulty": 1, "topics": [ @@ -36,6 +38,7 @@ }, { "slug": "resistor-color-duo", + "name": "Resistor Color Duo", "uuid": "57b0c57e-26a5-4ccf-aaf2-2fefddd918c1", "difficulty": 1, "topics": [ @@ -45,6 +48,7 @@ }, { "slug": "acronym", + "name": "Acronym", "uuid": "74468206-68a2-4efb-8caa-782634674c7f", "difficulty": 1, "topics": [ @@ -55,6 +59,7 @@ }, { "slug": "high-scores", + "name": "High Scores", "uuid": "9124339c-94fb-46eb-aad2-25944214799d", "difficulty": 2, "topics": [ @@ -63,6 +68,7 @@ }, { "slug": "matrix", + "name": "Matrix", "uuid": "3de21c18-a533-4150-8a73-49df8fcb8c61", "difficulty": 4, "topics": [ @@ -75,6 +81,7 @@ }, { "slug": "series", + "name": "Series", "uuid": "2de036e4-576d-47fc-bb03-4ed1612e79da", "difficulty": 3, "topics": [ @@ -85,6 +92,7 @@ }, { "slug": "word-count", + "name": "Word Count", "uuid": "e9d29769-8d4d-4159-8d6f-762db5339707", "difficulty": 3, "topics": [ @@ -95,6 +103,7 @@ }, { "slug": "hamming", + "name": "Hamming", "uuid": "d33dec8a-e2b4-40bc-8be9-3f49de084d43", "difficulty": 1, "topics": [ @@ -105,6 +114,7 @@ }, { "slug": "raindrops", + "name": "Raindrops", "uuid": "efad2cea-1e0b-4fb8-a452-a8e91be73638", "difficulty": 1, "topics": [ @@ -115,6 +125,7 @@ }, { "slug": "isogram", + "name": "Isogram", "uuid": "a79eb8cd-d2db-48f5-a7dc-055039dcee62", "difficulty": 2, "topics": [ @@ -125,6 +136,7 @@ }, { "slug": "scrabble-score", + "name": "Scrabble Score", "uuid": "d934ebce-9ac3-4a41-bcb8-d70480170438", "difficulty": 2, "topics": [ @@ -135,6 +147,7 @@ }, { "slug": "luhn", + "name": "Luhn", "uuid": "bee97539-b8c1-460e-aa14-9336008df2b6", "difficulty": 2, "topics": [ @@ -145,6 +158,7 @@ }, { "slug": "clock", + "name": "Clock", "uuid": "f95ebf09-0f32-4e60-867d-60cb81dd9a62", "difficulty": 3, "topics": [ @@ -155,6 +169,7 @@ }, { "slug": "twelve-days", + "name": "Twelve Days", "uuid": "eeb64dda-b79f-4920-8fa3-04810e8d37ab", "difficulty": 4, "topics": [ @@ -167,6 +182,7 @@ }, { "slug": "tournament", + "name": "Tournament", "uuid": "486becee-9d85-4139-ab89-db254d385ade", "difficulty": 3, "topics": [ @@ -181,6 +197,7 @@ }, { "slug": "gigasecond", + "name": "Gigasecond", "uuid": "0fb594a1-193b-4ccf-8de2-eb6a81708b29", "difficulty": 1, "topics": [ @@ -189,6 +206,7 @@ }, { "slug": "resistor-color", + "name": "Resistor Color", "uuid": "685634dd-0b38-40bc-b0ad-e8aa2904035f", "difficulty": 1, "topics": [ @@ -197,6 +215,7 @@ }, { "slug": "rna-transcription", + "name": "Rna Transcription", "uuid": "41f66d2a-1883-4a2c-875f-663c46fa88aa", "difficulty": 2, "topics": [ @@ -206,6 +225,7 @@ }, { "slug": "leap", + "name": "Leap", "uuid": "06eaa2dd-dc80-4d38-b10d-11174183b0b6", "difficulty": 1, "topics": [ @@ -217,6 +237,7 @@ }, { "slug": "pangram", + "name": "Pangram", "uuid": "fcf07149-b2cb-4042-90e6-fb3350e0fdf6", "difficulty": 2, "topics": [ @@ -226,6 +247,7 @@ }, { "slug": "space-age", + "name": "Space Age", "uuid": "c971a2b5-ccd4-4e55-9fc7-33e991bc0676", "difficulty": 2, "topics": [ @@ -235,6 +257,7 @@ }, { "slug": "triangle", + "name": "Triangle", "uuid": "5c797eb2-155d-47ca-8f85-2ba5803f9713", "difficulty": 3, "topics": [ @@ -245,6 +268,7 @@ }, { "slug": "difference-of-squares", + "name": "Difference Of Squares", "uuid": "f1e4ee0c-8718-43f2-90a5-fb1e915288da", "difficulty": 2, "topics": [ @@ -254,6 +278,7 @@ }, { "slug": "anagram", + "name": "Anagram", "uuid": "36df18ba-580d-4982-984e-ba50eb1f8c0b", "difficulty": 5, "topics": [ @@ -265,6 +290,7 @@ }, { "slug": "sum-of-multiples", + "name": "Sum Of Multiples", "uuid": "4fc25295-5d6a-4d13-9b87-064167d8980e", "difficulty": 5, "topics": [ @@ -274,6 +300,7 @@ }, { "slug": "transpose", + "name": "Transpose", "uuid": "4a6bc7d3-5d3b-4ad8-96ae-783e17af7c32", "difficulty": 5, "topics": [ @@ -284,6 +311,7 @@ }, { "slug": "armstrong-numbers", + "name": "Armstrong Numbers", "uuid": "77c5c7e6-265a-4f1a-9bc4-851f8f825420", "difficulty": 3, "topics": [ @@ -292,6 +320,7 @@ }, { "slug": "flatten-array", + "name": "Flatten Array", "uuid": "2df8ed82-2a04-4112-a17b-7813bcdc0e84", "difficulty": 3, "topics": [ @@ -301,6 +330,7 @@ }, { "slug": "phone-number", + "name": "Phone Number", "uuid": "b68665d5-14ef-4351-ac4a-c28a80c27b3d", "difficulty": 3, "topics": [ @@ -313,6 +343,7 @@ }, { "slug": "grains", + "name": "Grains", "uuid": "22519f53-4516-43bc-915e-07d58e48f617", "difficulty": 4, "topics": [ @@ -322,6 +353,7 @@ }, { "slug": "resistor-color-trio", + "name": "Resistor Color Trio", "uuid": "2df14b68-75c8-4984-8ae2-ecd2cb7ed1d4", "difficulty": 5, "topics": [ @@ -330,6 +362,7 @@ }, { "slug": "saddle-points", + "name": "Saddle Points", "uuid": "38bb4ac6-a5ec-4448-8b86-cdaff13a8be3", "difficulty": 5, "topics": [ @@ -341,6 +374,7 @@ }, { "slug": "etl", + "name": "Etl", "uuid": "0d66f3db-69a4-44b9-80be-9366f8b189ec", "difficulty": 4, "topics": [ @@ -351,6 +385,7 @@ }, { "slug": "nucleotide-count", + "name": "Nucleotide Count", "uuid": "8ad2bffd-1d79-4e1f-8ef3-ece0214d2804", "difficulty": 4, "topics": [ @@ -361,6 +396,7 @@ }, { "slug": "pythagorean-triplet", + "name": "Pythagorean Triplet", "uuid": "43aad536-0e24-464c-9554-cbc2699d0543", "difficulty": 5, "topics": [ @@ -370,6 +406,7 @@ }, { "slug": "collatz-conjecture", + "name": "Collatz Conjecture", "uuid": "af961c87-341c-4dd3-a1eb-272501b9b0e4", "difficulty": 1, "topics": [ @@ -381,6 +418,7 @@ }, { "slug": "sieve", + "name": "Sieve", "uuid": "80f9af5a-ea29-4937-9333-b4494aaf2446", "difficulty": 3, "topics": [ @@ -393,6 +431,7 @@ }, { "slug": "proverb", + "name": "Proverb", "uuid": "3c5193ab-6471-4be2-9d24-1d2b51ad822a", "difficulty": 4, "topics": [ @@ -403,6 +442,7 @@ }, { "slug": "palindrome-products", + "name": "Palindrome Products", "uuid": "abd68340-91b9-48c1-8567-79822bb2165c", "difficulty": 6, "topics": [ @@ -412,6 +452,7 @@ }, { "slug": "accumulate", + "name": "Accumulate", "uuid": "2c71fc3a-2c93-402b-b091-697b795ce3ba", "difficulty": 1, "topics": [ @@ -420,6 +461,7 @@ }, { "slug": "bob", + "name": "Bob", "uuid": "70fec82e-3038-468f-96ef-bfb48ce03ef3", "difficulty": 2, "topics": [ @@ -429,6 +471,7 @@ }, { "slug": "strain", + "name": "Strain", "uuid": "ac0966a9-822b-45be-91d9-36f6706ea76f", "difficulty": 2, "topics": [ @@ -439,6 +482,7 @@ }, { "slug": "nth-prime", + "name": "Nth Prime", "uuid": "16baef71-6234-4928-a2d4-a19eb8e110b8", "difficulty": 3, "topics": [ @@ -449,6 +493,7 @@ }, { "slug": "perfect-numbers", + "name": "Perfect Numbers", "uuid": "76ad732a-6e58-403b-ac65-9091d355241f", "difficulty": 4, "topics": [ @@ -460,6 +505,7 @@ }, { "slug": "alphametics", + "name": "Alphametics", "uuid": "2323a2a5-c181-4c1e-9c5f-f6b92b2de511", "difficulty": 5, "topics": [ @@ -470,6 +516,7 @@ }, { "slug": "binary-search", + "name": "Binary Search", "uuid": "b1ba445d-4908-4922-acc0-de3a0ec92c53", "difficulty": 5, "topics": [ @@ -481,6 +528,7 @@ }, { "slug": "two-bucket", + "name": "Two Bucket", "uuid": "e5a2d445-437d-46a8-889b-fbcd62c70fa9", "difficulty": 5, "topics": [ @@ -491,6 +539,7 @@ }, { "slug": "matching-brackets", + "name": "Matching Brackets", "uuid": "26f6e297-7980-4472-8ce7-157b62b0ff40", "difficulty": 7, "topics": [ @@ -500,6 +549,7 @@ }, { "slug": "all-your-base", + "name": "All Your Base", "uuid": "3ce4bd3e-0380-498a-8d0a-b79cf3fedc10", "difficulty": 3, "topics": [ @@ -510,6 +560,7 @@ }, { "slug": "scale-generator", + "name": "Scale Generator", "uuid": "4134d491-8ec5-480b-aa61-37a02689db1f", "difficulty": 3, "topics": [ @@ -519,6 +570,7 @@ }, { "slug": "allergies", + "name": "Allergies", "uuid": "b306bdaa-438e-46a2-ba54-82cb2c0be882", "difficulty": 4, "topics": [ @@ -528,6 +580,7 @@ }, { "slug": "rail-fence-cipher", + "name": "Rail Fence Cipher", "uuid": "64196fe5-2270-4113-a614-fbfbb6d00f2b", "difficulty": 4, "topics": [ @@ -542,6 +595,7 @@ }, { "slug": "run-length-encoding", + "name": "Run Length Encoding", "uuid": "9d6a8c89-41c1-4c4e-b24c-476ba0dfa5f9", "difficulty": 4, "topics": [ @@ -552,6 +606,7 @@ }, { "slug": "minesweeper", + "name": "Minesweeper", "uuid": "9d6808fb-d367-4df9-a1f0-47ff83b75544", "difficulty": 5, "topics": [ @@ -564,6 +619,7 @@ }, { "slug": "robot-simulator", + "name": "Robot Simulator", "uuid": "724e6a6e-2e6e-45a9-ab0e-0d8d50a06085", "difficulty": 6, "topics": [ @@ -576,6 +632,7 @@ }, { "slug": "beer-song", + "name": "Beer Song", "uuid": "50c34698-7767-42b3-962f-21c735e49787", "difficulty": 3, "topics": [ @@ -586,6 +643,7 @@ }, { "slug": "protein-translation", + "name": "Protein Translation", "uuid": "00c6f623-2e54-4f90-ae3f-07e493f93c7c", "difficulty": 3, "topics": [ @@ -596,6 +654,7 @@ }, { "slug": "wordy", + "name": "Wordy", "uuid": "cb58e4cf-e3af-469c-9f2d-02557b9f61ed", "difficulty": 3, "topics": [ @@ -608,6 +667,7 @@ }, { "slug": "secret-handshake", + "name": "Secret Handshake", "uuid": "c1ebad1b-d5aa-465a-b5ef-9e717ab5db9e", "difficulty": 5, "topics": [ @@ -618,6 +678,7 @@ }, { "slug": "atbash-cipher", + "name": "Atbash Cipher", "uuid": "1e737640-9785-4a47-866a-46298104d891", "difficulty": 3, "topics": [ @@ -629,6 +690,7 @@ }, { "slug": "crypto-square", + "name": "Crypto Square", "uuid": "86f8e33d-31b7-43e3-8ea3-2e391133704a", "difficulty": 3, "topics": [ @@ -641,6 +703,7 @@ }, { "slug": "list-ops", + "name": "List Ops", "uuid": "f62e8acb-8370-46e1-ad7f-a6a2644f8602", "difficulty": 3, "topics": [ @@ -652,6 +715,7 @@ }, { "slug": "robot-name", + "name": "Robot Name", "uuid": "76a0fd0a-cc65-4be3-acc8-7348bb67ad5a", "difficulty": 3, "topics": [ @@ -660,6 +724,7 @@ }, { "slug": "simple-cipher", + "name": "Simple Cipher", "uuid": "29c66e8a-b1b0-4bbd-be7b-9979ff51ba8f", "difficulty": 3, "topics": [ @@ -672,6 +737,7 @@ }, { "slug": "dominoes", + "name": "Dominoes", "uuid": "705f3eb6-55a9-476c-b3f2-e9f3cb0bbe37", "difficulty": 4, "topics": [ @@ -682,6 +748,7 @@ }, { "slug": "pig-latin", + "name": "Pig Latin", "uuid": "efc0e498-891a-4e91-a6aa-fae635573a83", "difficulty": 4, "topics": [ @@ -692,6 +759,7 @@ }, { "slug": "simple-linked-list", + "name": "Simple Linked List", "uuid": "fa7b91c2-842c-42c8-bdf9-00bb3e71a7f5", "difficulty": 4, "topics": [ @@ -701,6 +769,7 @@ }, { "slug": "binary-search-tree", + "name": "Binary Search Tree", "uuid": "0e05bfcf-17ae-4884-803a-fa1428bc1702", "difficulty": 5, "topics": [ @@ -714,6 +783,7 @@ }, { "slug": "change", + "name": "Change", "uuid": "dc6c3e44-1027-4d53-9653-ba06824f8bcf", "difficulty": 5, "topics": [ @@ -725,6 +795,7 @@ }, { "slug": "circular-buffer", + "name": "Circular Buffer", "uuid": "f3419fe3-a5f5-4bc9-bc40-49f450b8981e", "difficulty": 5, "topics": [ @@ -734,6 +805,7 @@ }, { "slug": "grade-school", + "name": "Grade School", "uuid": "4460742c-2beb-48d7-94e6-72ff13c68c71", "difficulty": 5, "topics": [ @@ -744,6 +816,7 @@ }, { "slug": "roman-numerals", + "name": "Roman Numerals", "uuid": "b7ca9519-c33b-418b-a4ef-858a3d4d6855", "difficulty": 2, "topics": [ @@ -753,6 +826,7 @@ }, { "slug": "rotational-cipher", + "name": "Rotational Cipher", "uuid": "af5ccf14-eff2-4dc6-b1db-e209cddca62a", "difficulty": 2, "topics": [ @@ -763,6 +837,7 @@ }, { "slug": "affine-cipher", + "name": "Affine Cipher", "uuid": "d1267415-aff5-411d-b267-49a4a2c8fda2", "difficulty": 3, "topics": [ @@ -773,6 +848,7 @@ }, { "slug": "kindergarten-garden", + "name": "Kindergarten Garden", "uuid": "04bde625-e363-4d8b-880f-db7bf86286eb", "difficulty": 3, "topics": [ @@ -785,6 +861,7 @@ }, { "slug": "largest-series-product", + "name": "Largest Series Product", "uuid": "7cb55328-1b11-4544-94c0-945444d9a6a4", "difficulty": 3, "topics": [ @@ -796,6 +873,7 @@ }, { "slug": "prime-factors", + "name": "Prime Factors", "uuid": "a18daa31-88d3-45ba-84ca-f1d52fe23a79", "difficulty": 3, "topics": [ @@ -806,6 +884,7 @@ }, { "slug": "custom-set", + "name": "Custom Set", "uuid": "4f74b3cd-f995-4b8c-9b57-23f073261d0e", "difficulty": 4, "topics": [ @@ -816,6 +895,7 @@ }, { "slug": "house", + "name": "House", "uuid": "df5d771a-e57b-4a96-8a29-9bd4ce7f88d2", "difficulty": 4, "topics": [ @@ -826,6 +906,7 @@ }, { "slug": "linked-list", + "name": "Linked List", "uuid": "92c9aafc-791d-4aaf-a136-9bee14f6ff95", "difficulty": 4, "topics": [ @@ -835,6 +916,7 @@ }, { "slug": "poker", + "name": "Poker", "uuid": "9a59ba44-34f5-410b-a1e6-9a5c47c52d9e", "difficulty": 5, "topics": [ @@ -848,6 +930,7 @@ }, { "slug": "isbn-verifier", + "name": "Isbn Verifier", "uuid": "a0aac827-8f7a-4065-9d05-a57009f5668d", "difficulty": 2, "topics": [ @@ -856,6 +939,7 @@ }, { "slug": "complex-numbers", + "name": "Complex Numbers", "uuid": "d75bd7c0-52c5-44f2-a046-f63cb332425f", "difficulty": 3, "topics": [ @@ -864,6 +948,7 @@ }, { "slug": "meetup", + "name": "Meetup", "uuid": "8120e133-9561-4f82-8081-10c19f7f6ba3", "difficulty": 3, "topics": [ @@ -875,6 +960,7 @@ }, { "slug": "diamond", + "name": "Diamond", "uuid": "c55c75fb-6140-4042-967a-39c75b7781bd", "difficulty": 4, "topics": [ @@ -887,6 +973,7 @@ }, { "slug": "bowling", + "name": "Bowling", "uuid": "051f0825-8357-4ca6-b24f-40a373deac19", "difficulty": 5, "topics": [ @@ -897,6 +984,7 @@ }, { "slug": "ocr-numbers", + "name": "Ocr Numbers", "uuid": "dd13bb29-589c-497d-9580-3f288f353fb2", "difficulty": 7, "topics": [ @@ -906,6 +994,7 @@ }, { "slug": "say", + "name": "Say", "uuid": "2a410923-6445-41fc-9cf3-a60209e1c1c2", "difficulty": 7, "topics": [ @@ -917,6 +1006,7 @@ }, { "slug": "zipper", + "name": "Zipper", "uuid": "239b8e79-2983-4ce0-9dda-9bb999e79d11", "difficulty": 7, "topics": [ @@ -925,6 +1015,7 @@ }, { "slug": "grep", + "name": "Grep", "uuid": "99485900-5d16-4848-af1c-2f1a62ad35ab", "difficulty": 8, "topics": [ @@ -938,6 +1029,7 @@ }, { "slug": "food-chain", + "name": "Food Chain", "uuid": "6f0919eb-2160-4cca-8504-286acc2ae9c8", "difficulty": 4, "topics": [ @@ -950,6 +1042,7 @@ }, { "slug": "pascals-triangle", + "name": "Pascals Triangle", "uuid": "4ff8b056-f27d-4bdf-b7af-214448db4260", "difficulty": 4, "topics": [ @@ -961,6 +1054,7 @@ }, { "slug": "queen-attack", + "name": "Queen Attack", "uuid": "2ce9b158-e730-4c86-8639-bd08af9f80f4", "difficulty": 5, "topics": [ @@ -972,6 +1066,7 @@ }, { "slug": "book-store", + "name": "Book Store", "uuid": "0ec96460-08be-49a0-973a-4336f21b763c", "difficulty": 8, "topics": [ @@ -983,6 +1078,7 @@ }, { "slug": "connect", + "name": "Connect", "uuid": "538a6768-bae5-437c-9cdf-765d73a79643", "difficulty": 9, "topics": [ @@ -995,6 +1091,7 @@ }, { "slug": "binary", + "name": "Binary", "uuid": "43bc27ed-d2fa-4173-8665-4459b71c9a3a", "difficulty": 0, "topics": null, @@ -1002,6 +1099,7 @@ }, { "slug": "hexadecimal", + "name": "Hexadecimal", "uuid": "6984cc14-91f8-47a7-b7e2-4b210a5dbc5c", "difficulty": 0, "topics": null, @@ -1009,6 +1107,7 @@ }, { "slug": "octal", + "name": "Octal", "uuid": "cae4e000-3aac-41f7-b727-f9cce12d058d", "difficulty": 0, "topics": null, @@ -1016,6 +1115,7 @@ }, { "slug": "point-mutations", + "name": "Point Mutations", "uuid": "89bd3d71-000f-4cd9-9a84-ad1b22ddbd33", "difficulty": 0, "topics": null, @@ -1023,6 +1123,7 @@ }, { "slug": "trinary", + "name": "Trinary", "uuid": "f6735416-4be6-4eb8-b6b9-cb61671ce25e", "difficulty": 0, "topics": null, @@ -1030,6 +1131,7 @@ }, { "slug": "microwave", + "name": "Microwave", "uuid": "b960d0fe-a07f-11ea-bb37-0242ac130002", "difficulty": 2, "topics": [ @@ -1040,6 +1142,7 @@ }, { "slug": "darts", + "name": "Darts", "uuid": "15b73808-78a4-4854-b7cf-82a478107024", "difficulty": 3, "topics": [ From 22dc6e0c83c45b829c3fc84d8ba0ad61a048bfbf Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:46 +0100 Subject: [PATCH 091/102] [v3] Add (empty) prerequisites property to practice exercises in config.json --- config.json | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/config.json b/config.json index 4d731917b8..e8466fd873 100644 --- a/config.json +++ b/config.json @@ -21,6 +21,7 @@ "slug": "hello-world", "name": "Hello World", "uuid": "4fe19484-4414-471b-a106-73c776c61388", + "prerequisites": [], "difficulty": 1, "topics": [ "strings" @@ -30,6 +31,7 @@ "slug": "two-fer", "name": "Two Fer", "uuid": "1304b188-6d08-4361-be40-c6b1b88e5e54", + "prerequisites": [], "difficulty": 1, "topics": [ "conditionals", @@ -40,6 +42,7 @@ "slug": "resistor-color-duo", "name": "Resistor Color Duo", "uuid": "57b0c57e-26a5-4ccf-aaf2-2fefddd918c1", + "prerequisites": [], "difficulty": 1, "topics": [ "array", @@ -50,6 +53,7 @@ "slug": "acronym", "name": "Acronym", "uuid": "74468206-68a2-4efb-8caa-782634674c7f", + "prerequisites": [], "difficulty": 1, "topics": [ "regular_expressions", @@ -61,6 +65,7 @@ "slug": "high-scores", "name": "High Scores", "uuid": "9124339c-94fb-46eb-aad2-25944214799d", + "prerequisites": [], "difficulty": 2, "topics": [ "arrays" @@ -70,6 +75,7 @@ "slug": "matrix", "name": "Matrix", "uuid": "3de21c18-a533-4150-8a73-49df8fcb8c61", + "prerequisites": [], "difficulty": 4, "topics": [ "arrays", @@ -83,6 +89,7 @@ "slug": "series", "name": "Series", "uuid": "2de036e4-576d-47fc-bb03-4ed1612e79da", + "prerequisites": [], "difficulty": 3, "topics": [ "arrays", @@ -94,6 +101,7 @@ "slug": "word-count", "name": "Word Count", "uuid": "e9d29769-8d4d-4159-8d6f-762db5339707", + "prerequisites": [], "difficulty": 3, "topics": [ "enumerable", @@ -105,6 +113,7 @@ "slug": "hamming", "name": "Hamming", "uuid": "d33dec8a-e2b4-40bc-8be9-3f49de084d43", + "prerequisites": [], "difficulty": 1, "topics": [ "equality", @@ -116,6 +125,7 @@ "slug": "raindrops", "name": "Raindrops", "uuid": "efad2cea-1e0b-4fb8-a452-a8e91be73638", + "prerequisites": [], "difficulty": 1, "topics": [ "conditionals", @@ -127,6 +137,7 @@ "slug": "isogram", "name": "Isogram", "uuid": "a79eb8cd-d2db-48f5-a7dc-055039dcee62", + "prerequisites": [], "difficulty": 2, "topics": [ "regular_expressions", @@ -138,6 +149,7 @@ "slug": "scrabble-score", "name": "Scrabble Score", "uuid": "d934ebce-9ac3-4a41-bcb8-d70480170438", + "prerequisites": [], "difficulty": 2, "topics": [ "loops", @@ -149,6 +161,7 @@ "slug": "luhn", "name": "Luhn", "uuid": "bee97539-b8c1-460e-aa14-9336008df2b6", + "prerequisites": [], "difficulty": 2, "topics": [ "algorithms", @@ -160,6 +173,7 @@ "slug": "clock", "name": "Clock", "uuid": "f95ebf09-0f32-4e60-867d-60cb81dd9a62", + "prerequisites": [], "difficulty": 3, "topics": [ "equality", @@ -171,6 +185,7 @@ "slug": "twelve-days", "name": "Twelve Days", "uuid": "eeb64dda-b79f-4920-8fa3-04810e8d37ab", + "prerequisites": [], "difficulty": 4, "topics": [ "algorithms", @@ -184,6 +199,7 @@ "slug": "tournament", "name": "Tournament", "uuid": "486becee-9d85-4139-ab89-db254d385ade", + "prerequisites": [], "difficulty": 3, "topics": [ "integers", @@ -199,6 +215,7 @@ "slug": "gigasecond", "name": "Gigasecond", "uuid": "0fb594a1-193b-4ccf-8de2-eb6a81708b29", + "prerequisites": [], "difficulty": 1, "topics": [ "time" @@ -208,6 +225,7 @@ "slug": "resistor-color", "name": "Resistor Color", "uuid": "685634dd-0b38-40bc-b0ad-e8aa2904035f", + "prerequisites": [], "difficulty": 1, "topics": [ "arrays" @@ -217,6 +235,7 @@ "slug": "rna-transcription", "name": "Rna Transcription", "uuid": "41f66d2a-1883-4a2c-875f-663c46fa88aa", + "prerequisites": [], "difficulty": 2, "topics": [ "maps", @@ -227,6 +246,7 @@ "slug": "leap", "name": "Leap", "uuid": "06eaa2dd-dc80-4d38-b10d-11174183b0b6", + "prerequisites": [], "difficulty": 1, "topics": [ "booleans", @@ -239,6 +259,7 @@ "slug": "pangram", "name": "Pangram", "uuid": "fcf07149-b2cb-4042-90e6-fb3350e0fdf6", + "prerequisites": [], "difficulty": 2, "topics": [ "loops", @@ -249,6 +270,7 @@ "slug": "space-age", "name": "Space Age", "uuid": "c971a2b5-ccd4-4e55-9fc7-33e991bc0676", + "prerequisites": [], "difficulty": 2, "topics": [ "floating_point_numbers", @@ -259,6 +281,7 @@ "slug": "triangle", "name": "Triangle", "uuid": "5c797eb2-155d-47ca-8f85-2ba5803f9713", + "prerequisites": [], "difficulty": 3, "topics": [ "booleans", @@ -270,6 +293,7 @@ "slug": "difference-of-squares", "name": "Difference Of Squares", "uuid": "f1e4ee0c-8718-43f2-90a5-fb1e915288da", + "prerequisites": [], "difficulty": 2, "topics": [ "algorithms", @@ -280,6 +304,7 @@ "slug": "anagram", "name": "Anagram", "uuid": "36df18ba-580d-4982-984e-ba50eb1f8c0b", + "prerequisites": [], "difficulty": 5, "topics": [ "filtering", @@ -292,6 +317,7 @@ "slug": "sum-of-multiples", "name": "Sum Of Multiples", "uuid": "4fc25295-5d6a-4d13-9b87-064167d8980e", + "prerequisites": [], "difficulty": 5, "topics": [ "loops", @@ -302,6 +328,7 @@ "slug": "transpose", "name": "Transpose", "uuid": "4a6bc7d3-5d3b-4ad8-96ae-783e17af7c32", + "prerequisites": [], "difficulty": 5, "topics": [ "loops", @@ -313,6 +340,7 @@ "slug": "armstrong-numbers", "name": "Armstrong Numbers", "uuid": "77c5c7e6-265a-4f1a-9bc4-851f8f825420", + "prerequisites": [], "difficulty": 3, "topics": [ "math" @@ -322,6 +350,7 @@ "slug": "flatten-array", "name": "Flatten Array", "uuid": "2df8ed82-2a04-4112-a17b-7813bcdc0e84", + "prerequisites": [], "difficulty": 3, "topics": [ "arrays", @@ -332,6 +361,7 @@ "slug": "phone-number", "name": "Phone Number", "uuid": "b68665d5-14ef-4351-ac4a-c28a80c27b3d", + "prerequisites": [], "difficulty": 3, "topics": [ "conditionals", @@ -345,6 +375,7 @@ "slug": "grains", "name": "Grains", "uuid": "22519f53-4516-43bc-915e-07d58e48f617", + "prerequisites": [], "difficulty": 4, "topics": [ "bitwise_operations", @@ -355,6 +386,7 @@ "slug": "resistor-color-trio", "name": "Resistor Color Trio", "uuid": "2df14b68-75c8-4984-8ae2-ecd2cb7ed1d4", + "prerequisites": [], "difficulty": 5, "topics": [ "loops" @@ -364,6 +396,7 @@ "slug": "saddle-points", "name": "Saddle Points", "uuid": "38bb4ac6-a5ec-4448-8b86-cdaff13a8be3", + "prerequisites": [], "difficulty": 5, "topics": [ "arrays", @@ -376,6 +409,7 @@ "slug": "etl", "name": "Etl", "uuid": "0d66f3db-69a4-44b9-80be-9366f8b189ec", + "prerequisites": [], "difficulty": 4, "topics": [ "loops", @@ -387,6 +421,7 @@ "slug": "nucleotide-count", "name": "Nucleotide Count", "uuid": "8ad2bffd-1d79-4e1f-8ef3-ece0214d2804", + "prerequisites": [], "difficulty": 4, "topics": [ "maps", @@ -398,6 +433,7 @@ "slug": "pythagorean-triplet", "name": "Pythagorean Triplet", "uuid": "43aad536-0e24-464c-9554-cbc2699d0543", + "prerequisites": [], "difficulty": 5, "topics": [ "algorithms", @@ -408,6 +444,7 @@ "slug": "collatz-conjecture", "name": "Collatz Conjecture", "uuid": "af961c87-341c-4dd3-a1eb-272501b9b0e4", + "prerequisites": [], "difficulty": 1, "topics": [ "conditionals", @@ -420,6 +457,7 @@ "slug": "sieve", "name": "Sieve", "uuid": "80f9af5a-ea29-4937-9333-b4494aaf2446", + "prerequisites": [], "difficulty": 3, "topics": [ "algorithms", @@ -433,6 +471,7 @@ "slug": "proverb", "name": "Proverb", "uuid": "3c5193ab-6471-4be2-9d24-1d2b51ad822a", + "prerequisites": [], "difficulty": 4, "topics": [ "arrays", @@ -444,6 +483,7 @@ "slug": "palindrome-products", "name": "Palindrome Products", "uuid": "abd68340-91b9-48c1-8567-79822bb2165c", + "prerequisites": [], "difficulty": 6, "topics": [ "algorithms", @@ -454,6 +494,7 @@ "slug": "accumulate", "name": "Accumulate", "uuid": "2c71fc3a-2c93-402b-b091-697b795ce3ba", + "prerequisites": [], "difficulty": 1, "topics": [ "lists" @@ -463,6 +504,7 @@ "slug": "bob", "name": "Bob", "uuid": "70fec82e-3038-468f-96ef-bfb48ce03ef3", + "prerequisites": [], "difficulty": 2, "topics": [ "conditionals", @@ -473,6 +515,7 @@ "slug": "strain", "name": "Strain", "uuid": "ac0966a9-822b-45be-91d9-36f6706ea76f", + "prerequisites": [], "difficulty": 2, "topics": [ "arrays", @@ -484,6 +527,7 @@ "slug": "nth-prime", "name": "Nth Prime", "uuid": "16baef71-6234-4928-a2d4-a19eb8e110b8", + "prerequisites": [], "difficulty": 3, "topics": [ "algorithms", @@ -495,6 +539,7 @@ "slug": "perfect-numbers", "name": "Perfect Numbers", "uuid": "76ad732a-6e58-403b-ac65-9091d355241f", + "prerequisites": [], "difficulty": 4, "topics": [ "algorithms", @@ -507,6 +552,7 @@ "slug": "alphametics", "name": "Alphametics", "uuid": "2323a2a5-c181-4c1e-9c5f-f6b92b2de511", + "prerequisites": [], "difficulty": 5, "topics": [ "algorithms", @@ -518,6 +564,7 @@ "slug": "binary-search", "name": "Binary Search", "uuid": "b1ba445d-4908-4922-acc0-de3a0ec92c53", + "prerequisites": [], "difficulty": 5, "topics": [ "algorithms", @@ -530,6 +577,7 @@ "slug": "two-bucket", "name": "Two Bucket", "uuid": "e5a2d445-437d-46a8-889b-fbcd62c70fa9", + "prerequisites": [], "difficulty": 5, "topics": [ "algorithms", @@ -541,6 +589,7 @@ "slug": "matching-brackets", "name": "Matching Brackets", "uuid": "26f6e297-7980-4472-8ce7-157b62b0ff40", + "prerequisites": [], "difficulty": 7, "topics": [ "parsing", @@ -551,6 +600,7 @@ "slug": "all-your-base", "name": "All Your Base", "uuid": "3ce4bd3e-0380-498a-8d0a-b79cf3fedc10", + "prerequisites": [], "difficulty": 3, "topics": [ "integers", @@ -562,6 +612,7 @@ "slug": "scale-generator", "name": "Scale Generator", "uuid": "4134d491-8ec5-480b-aa61-37a02689db1f", + "prerequisites": [], "difficulty": 3, "topics": [ "pattern_matching", @@ -572,6 +623,7 @@ "slug": "allergies", "name": "Allergies", "uuid": "b306bdaa-438e-46a2-ba54-82cb2c0be882", + "prerequisites": [], "difficulty": 4, "topics": [ "bitwise_operations", @@ -582,6 +634,7 @@ "slug": "rail-fence-cipher", "name": "Rail Fence Cipher", "uuid": "64196fe5-2270-4113-a614-fbfbb6d00f2b", + "prerequisites": [], "difficulty": 4, "topics": [ "algorithms", @@ -597,6 +650,7 @@ "slug": "run-length-encoding", "name": "Run Length Encoding", "uuid": "9d6a8c89-41c1-4c4e-b24c-476ba0dfa5f9", + "prerequisites": [], "difficulty": 4, "topics": [ "parsing", @@ -608,6 +662,7 @@ "slug": "minesweeper", "name": "Minesweeper", "uuid": "9d6808fb-d367-4df9-a1f0-47ff83b75544", + "prerequisites": [], "difficulty": 5, "topics": [ "arrays", @@ -621,6 +676,7 @@ "slug": "robot-simulator", "name": "Robot Simulator", "uuid": "724e6a6e-2e6e-45a9-ab0e-0d8d50a06085", + "prerequisites": [], "difficulty": 6, "topics": [ "concurrency", @@ -634,6 +690,7 @@ "slug": "beer-song", "name": "Beer Song", "uuid": "50c34698-7767-42b3-962f-21c735e49787", + "prerequisites": [], "difficulty": 3, "topics": [ "loops", @@ -645,6 +702,7 @@ "slug": "protein-translation", "name": "Protein Translation", "uuid": "00c6f623-2e54-4f90-ae3f-07e493f93c7c", + "prerequisites": [], "difficulty": 3, "topics": [ "filtering", @@ -656,6 +714,7 @@ "slug": "wordy", "name": "Wordy", "uuid": "cb58e4cf-e3af-469c-9f2d-02557b9f61ed", + "prerequisites": [], "difficulty": 3, "topics": [ "conditionals", @@ -669,6 +728,7 @@ "slug": "secret-handshake", "name": "Secret Handshake", "uuid": "c1ebad1b-d5aa-465a-b5ef-9e717ab5db9e", + "prerequisites": [], "difficulty": 5, "topics": [ "arrays", @@ -680,6 +740,7 @@ "slug": "atbash-cipher", "name": "Atbash Cipher", "uuid": "1e737640-9785-4a47-866a-46298104d891", + "prerequisites": [], "difficulty": 3, "topics": [ "algorithms", @@ -692,6 +753,7 @@ "slug": "crypto-square", "name": "Crypto Square", "uuid": "86f8e33d-31b7-43e3-8ea3-2e391133704a", + "prerequisites": [], "difficulty": 3, "topics": [ "cryptography", @@ -705,6 +767,7 @@ "slug": "list-ops", "name": "List Ops", "uuid": "f62e8acb-8370-46e1-ad7f-a6a2644f8602", + "prerequisites": [], "difficulty": 3, "topics": [ "functional_programming", @@ -717,6 +780,7 @@ "slug": "robot-name", "name": "Robot Name", "uuid": "76a0fd0a-cc65-4be3-acc8-7348bb67ad5a", + "prerequisites": [], "difficulty": 3, "topics": [ "randomness" @@ -726,6 +790,7 @@ "slug": "simple-cipher", "name": "Simple Cipher", "uuid": "29c66e8a-b1b0-4bbd-be7b-9979ff51ba8f", + "prerequisites": [], "difficulty": 3, "topics": [ "algorithms", @@ -739,6 +804,7 @@ "slug": "dominoes", "name": "Dominoes", "uuid": "705f3eb6-55a9-476c-b3f2-e9f3cb0bbe37", + "prerequisites": [], "difficulty": 4, "topics": [ "algorithms", @@ -750,6 +816,7 @@ "slug": "pig-latin", "name": "Pig Latin", "uuid": "efc0e498-891a-4e91-a6aa-fae635573a83", + "prerequisites": [], "difficulty": 4, "topics": [ "conditionals", @@ -761,6 +828,7 @@ "slug": "simple-linked-list", "name": "Simple Linked List", "uuid": "fa7b91c2-842c-42c8-bdf9-00bb3e71a7f5", + "prerequisites": [], "difficulty": 4, "topics": [ "arrays", @@ -771,6 +839,7 @@ "slug": "binary-search-tree", "name": "Binary Search Tree", "uuid": "0e05bfcf-17ae-4884-803a-fa1428bc1702", + "prerequisites": [], "difficulty": 5, "topics": [ "algorithms", @@ -785,6 +854,7 @@ "slug": "change", "name": "Change", "uuid": "dc6c3e44-1027-4d53-9653-ba06824f8bcf", + "prerequisites": [], "difficulty": 5, "topics": [ "algorithms", @@ -797,6 +867,7 @@ "slug": "circular-buffer", "name": "Circular Buffer", "uuid": "f3419fe3-a5f5-4bc9-bc40-49f450b8981e", + "prerequisites": [], "difficulty": 5, "topics": [ "queues", @@ -807,6 +878,7 @@ "slug": "grade-school", "name": "Grade School", "uuid": "4460742c-2beb-48d7-94e6-72ff13c68c71", + "prerequisites": [], "difficulty": 5, "topics": [ "lists", @@ -818,6 +890,7 @@ "slug": "roman-numerals", "name": "Roman Numerals", "uuid": "b7ca9519-c33b-418b-a4ef-858a3d4d6855", + "prerequisites": [], "difficulty": 2, "topics": [ "numbers", @@ -828,6 +901,7 @@ "slug": "rotational-cipher", "name": "Rotational Cipher", "uuid": "af5ccf14-eff2-4dc6-b1db-e209cddca62a", + "prerequisites": [], "difficulty": 2, "topics": [ "cryptography", @@ -839,6 +913,7 @@ "slug": "affine-cipher", "name": "Affine Cipher", "uuid": "d1267415-aff5-411d-b267-49a4a2c8fda2", + "prerequisites": [], "difficulty": 3, "topics": [ "cryptography", @@ -850,6 +925,7 @@ "slug": "kindergarten-garden", "name": "Kindergarten Garden", "uuid": "04bde625-e363-4d8b-880f-db7bf86286eb", + "prerequisites": [], "difficulty": 3, "topics": [ "parsing", @@ -863,6 +939,7 @@ "slug": "largest-series-product", "name": "Largest Series Product", "uuid": "7cb55328-1b11-4544-94c0-945444d9a6a4", + "prerequisites": [], "difficulty": 3, "topics": [ "algorithms", @@ -875,6 +952,7 @@ "slug": "prime-factors", "name": "Prime Factors", "uuid": "a18daa31-88d3-45ba-84ca-f1d52fe23a79", + "prerequisites": [], "difficulty": 3, "topics": [ "algorithms", @@ -886,6 +964,7 @@ "slug": "custom-set", "name": "Custom Set", "uuid": "4f74b3cd-f995-4b8c-9b57-23f073261d0e", + "prerequisites": [], "difficulty": 4, "topics": [ "filtering", @@ -897,6 +976,7 @@ "slug": "house", "name": "House", "uuid": "df5d771a-e57b-4a96-8a29-9bd4ce7f88d2", + "prerequisites": [], "difficulty": 4, "topics": [ "recursion", @@ -908,6 +988,7 @@ "slug": "linked-list", "name": "Linked List", "uuid": "92c9aafc-791d-4aaf-a136-9bee14f6ff95", + "prerequisites": [], "difficulty": 4, "topics": [ "data_structure", @@ -918,6 +999,7 @@ "slug": "poker", "name": "Poker", "uuid": "9a59ba44-34f5-410b-a1e6-9a5c47c52d9e", + "prerequisites": [], "difficulty": 5, "topics": [ "equality", @@ -932,6 +1014,7 @@ "slug": "isbn-verifier", "name": "Isbn Verifier", "uuid": "a0aac827-8f7a-4065-9d05-a57009f5668d", + "prerequisites": [], "difficulty": 2, "topics": [ "arrays" @@ -941,6 +1024,7 @@ "slug": "complex-numbers", "name": "Complex Numbers", "uuid": "d75bd7c0-52c5-44f2-a046-f63cb332425f", + "prerequisites": [], "difficulty": 3, "topics": [ "math" @@ -950,6 +1034,7 @@ "slug": "meetup", "name": "Meetup", "uuid": "8120e133-9561-4f82-8081-10c19f7f6ba3", + "prerequisites": [], "difficulty": 3, "topics": [ "dates", @@ -962,6 +1047,7 @@ "slug": "diamond", "name": "Diamond", "uuid": "c55c75fb-6140-4042-967a-39c75b7781bd", + "prerequisites": [], "difficulty": 4, "topics": [ "algorithms", @@ -975,6 +1061,7 @@ "slug": "bowling", "name": "Bowling", "uuid": "051f0825-8357-4ca6-b24f-40a373deac19", + "prerequisites": [], "difficulty": 5, "topics": [ "algorithms", @@ -986,6 +1073,7 @@ "slug": "ocr-numbers", "name": "Ocr Numbers", "uuid": "dd13bb29-589c-497d-9580-3f288f353fb2", + "prerequisites": [], "difficulty": 7, "topics": [ "parsing", @@ -996,6 +1084,7 @@ "slug": "say", "name": "Say", "uuid": "2a410923-6445-41fc-9cf3-a60209e1c1c2", + "prerequisites": [], "difficulty": 7, "topics": [ "numbers", @@ -1008,6 +1097,7 @@ "slug": "zipper", "name": "Zipper", "uuid": "239b8e79-2983-4ce0-9dda-9bb999e79d11", + "prerequisites": [], "difficulty": 7, "topics": [ "data_structures" @@ -1017,6 +1107,7 @@ "slug": "grep", "name": "Grep", "uuid": "99485900-5d16-4848-af1c-2f1a62ad35ab", + "prerequisites": [], "difficulty": 8, "topics": [ "files", @@ -1031,6 +1122,7 @@ "slug": "food-chain", "name": "Food Chain", "uuid": "6f0919eb-2160-4cca-8504-286acc2ae9c8", + "prerequisites": [], "difficulty": 4, "topics": [ "conditionals", @@ -1044,6 +1136,7 @@ "slug": "pascals-triangle", "name": "Pascals Triangle", "uuid": "4ff8b056-f27d-4bdf-b7af-214448db4260", + "prerequisites": [], "difficulty": 4, "topics": [ "algorithms", @@ -1056,6 +1149,7 @@ "slug": "queen-attack", "name": "Queen Attack", "uuid": "2ce9b158-e730-4c86-8639-bd08af9f80f4", + "prerequisites": [], "difficulty": 5, "topics": [ "booleans", @@ -1068,6 +1162,7 @@ "slug": "book-store", "name": "Book Store", "uuid": "0ec96460-08be-49a0-973a-4336f21b763c", + "prerequisites": [], "difficulty": 8, "topics": [ "algorithms", @@ -1080,6 +1175,7 @@ "slug": "connect", "name": "Connect", "uuid": "538a6768-bae5-437c-9cdf-765d73a79643", + "prerequisites": [], "difficulty": 9, "topics": [ "arrays", @@ -1093,6 +1189,7 @@ "slug": "binary", "name": "Binary", "uuid": "43bc27ed-d2fa-4173-8665-4459b71c9a3a", + "prerequisites": [], "difficulty": 0, "topics": null, "status": "deprecated" @@ -1101,6 +1198,7 @@ "slug": "hexadecimal", "name": "Hexadecimal", "uuid": "6984cc14-91f8-47a7-b7e2-4b210a5dbc5c", + "prerequisites": [], "difficulty": 0, "topics": null, "status": "deprecated" @@ -1109,6 +1207,7 @@ "slug": "octal", "name": "Octal", "uuid": "cae4e000-3aac-41f7-b727-f9cce12d058d", + "prerequisites": [], "difficulty": 0, "topics": null, "status": "deprecated" @@ -1117,6 +1216,7 @@ "slug": "point-mutations", "name": "Point Mutations", "uuid": "89bd3d71-000f-4cd9-9a84-ad1b22ddbd33", + "prerequisites": [], "difficulty": 0, "topics": null, "status": "deprecated" @@ -1125,6 +1225,7 @@ "slug": "trinary", "name": "Trinary", "uuid": "f6735416-4be6-4eb8-b6b9-cb61671ce25e", + "prerequisites": [], "difficulty": 0, "topics": null, "status": "deprecated" @@ -1133,6 +1234,7 @@ "slug": "microwave", "name": "Microwave", "uuid": "b960d0fe-a07f-11ea-bb37-0242ac130002", + "prerequisites": [], "difficulty": 2, "topics": [ "math", @@ -1144,6 +1246,7 @@ "slug": "darts", "name": "Darts", "uuid": "15b73808-78a4-4854-b7cf-82a478107024", + "prerequisites": [], "difficulty": 3, "topics": [ "math", From eab77066fcf90729183d8ab6159f8ceeef0992b4 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:46 +0100 Subject: [PATCH 092/102] [v3] Move exercises to practice exercises property in config.json --- config.json | 2478 ++++++++++++++++++++++++++------------------------- 1 file changed, 1240 insertions(+), 1238 deletions(-) diff --git a/config.json b/config.json index e8466fd873..24bd07cef7 100644 --- a/config.json +++ b/config.json @@ -16,1242 +16,1244 @@ "indent_style": "space", "indent_size": 2 }, - "exercises": [ - { - "slug": "hello-world", - "name": "Hello World", - "uuid": "4fe19484-4414-471b-a106-73c776c61388", - "prerequisites": [], - "difficulty": 1, - "topics": [ - "strings" - ] - }, - { - "slug": "two-fer", - "name": "Two Fer", - "uuid": "1304b188-6d08-4361-be40-c6b1b88e5e54", - "prerequisites": [], - "difficulty": 1, - "topics": [ - "conditionals", - "strings" - ] - }, - { - "slug": "resistor-color-duo", - "name": "Resistor Color Duo", - "uuid": "57b0c57e-26a5-4ccf-aaf2-2fefddd918c1", - "prerequisites": [], - "difficulty": 1, - "topics": [ - "array", - "loops" - ] - }, - { - "slug": "acronym", - "name": "Acronym", - "uuid": "74468206-68a2-4efb-8caa-782634674c7f", - "prerequisites": [], - "difficulty": 1, - "topics": [ - "regular_expressions", - "strings", - "transforming" - ] - }, - { - "slug": "high-scores", - "name": "High Scores", - "uuid": "9124339c-94fb-46eb-aad2-25944214799d", - "prerequisites": [], - "difficulty": 2, - "topics": [ - "arrays" - ] - }, - { - "slug": "matrix", - "name": "Matrix", - "uuid": "3de21c18-a533-4150-8a73-49df8fcb8c61", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "arrays", - "exception_handling", - "matrices", - "strings", - "type_conversion" - ] - }, - { - "slug": "series", - "name": "Series", - "uuid": "2de036e4-576d-47fc-bb03-4ed1612e79da", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "arrays", - "enumerable", - "loops" - ] - }, - { - "slug": "word-count", - "name": "Word Count", - "uuid": "e9d29769-8d4d-4159-8d6f-762db5339707", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "enumerable", - "hash", - "loops" - ] - }, - { - "slug": "hamming", - "name": "Hamming", - "uuid": "d33dec8a-e2b4-40bc-8be9-3f49de084d43", - "prerequisites": [], - "difficulty": 1, - "topics": [ - "equality", - "loops", - "strings" - ] - }, - { - "slug": "raindrops", - "name": "Raindrops", - "uuid": "efad2cea-1e0b-4fb8-a452-a8e91be73638", - "prerequisites": [], - "difficulty": 1, - "topics": [ - "conditionals", - "filtering", - "strings" - ] - }, - { - "slug": "isogram", - "name": "Isogram", - "uuid": "a79eb8cd-d2db-48f5-a7dc-055039dcee62", - "prerequisites": [], - "difficulty": 2, - "topics": [ - "regular_expressions", - "sequences", - "strings" - ] - }, - { - "slug": "scrabble-score", - "name": "Scrabble Score", - "uuid": "d934ebce-9ac3-4a41-bcb8-d70480170438", - "prerequisites": [], - "difficulty": 2, - "topics": [ - "loops", - "maps", - "strings" - ] - }, - { - "slug": "luhn", - "name": "Luhn", - "uuid": "bee97539-b8c1-460e-aa14-9336008df2b6", - "prerequisites": [], - "difficulty": 2, - "topics": [ - "algorithms", - "integers", - "strings" - ] - }, - { - "slug": "clock", - "name": "Clock", - "uuid": "f95ebf09-0f32-4e60-867d-60cb81dd9a62", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "equality", - "text_formatting", - "time" - ] - }, - { - "slug": "twelve-days", - "name": "Twelve Days", - "uuid": "eeb64dda-b79f-4920-8fa3-04810e8d37ab", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "algorithms", - "pattern_recognition", - "sequences", - "strings", - "text_formatting" - ] - }, - { - "slug": "tournament", - "name": "Tournament", - "uuid": "486becee-9d85-4139-ab89-db254d385ade", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "integers", - "parsing", - "records", - "sorting", - "strings", - "text_formatting", - "transforming" - ] - }, - { - "slug": "gigasecond", - "name": "Gigasecond", - "uuid": "0fb594a1-193b-4ccf-8de2-eb6a81708b29", - "prerequisites": [], - "difficulty": 1, - "topics": [ - "time" - ] - }, - { - "slug": "resistor-color", - "name": "Resistor Color", - "uuid": "685634dd-0b38-40bc-b0ad-e8aa2904035f", - "prerequisites": [], - "difficulty": 1, - "topics": [ - "arrays" - ] - }, - { - "slug": "rna-transcription", - "name": "Rna Transcription", - "uuid": "41f66d2a-1883-4a2c-875f-663c46fa88aa", - "prerequisites": [], - "difficulty": 2, - "topics": [ - "maps", - "transforming" - ] - }, - { - "slug": "leap", - "name": "Leap", - "uuid": "06eaa2dd-dc80-4d38-b10d-11174183b0b6", - "prerequisites": [], - "difficulty": 1, - "topics": [ - "booleans", - "conditionals", - "integers", - "logic" - ] - }, - { - "slug": "pangram", - "name": "Pangram", - "uuid": "fcf07149-b2cb-4042-90e6-fb3350e0fdf6", - "prerequisites": [], - "difficulty": 2, - "topics": [ - "loops", - "strings" - ] - }, - { - "slug": "space-age", - "name": "Space Age", - "uuid": "c971a2b5-ccd4-4e55-9fc7-33e991bc0676", - "prerequisites": [], - "difficulty": 2, - "topics": [ - "floating_point_numbers", - "if_else_statements" - ] - }, - { - "slug": "triangle", - "name": "Triangle", - "uuid": "5c797eb2-155d-47ca-8f85-2ba5803f9713", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "booleans", - "conditionals", - "logic" - ] - }, - { - "slug": "difference-of-squares", - "name": "Difference Of Squares", - "uuid": "f1e4ee0c-8718-43f2-90a5-fb1e915288da", - "prerequisites": [], - "difficulty": 2, - "topics": [ - "algorithms", - "math" - ] - }, - { - "slug": "anagram", - "name": "Anagram", - "uuid": "36df18ba-580d-4982-984e-ba50eb1f8c0b", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "filtering", - "parsing", - "sorting", - "strings" - ] - }, - { - "slug": "sum-of-multiples", - "name": "Sum Of Multiples", - "uuid": "4fc25295-5d6a-4d13-9b87-064167d8980e", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "loops", - "math" - ] - }, - { - "slug": "transpose", - "name": "Transpose", - "uuid": "4a6bc7d3-5d3b-4ad8-96ae-783e17af7c32", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "loops", - "strings", - "transforming" - ] - }, - { - "slug": "armstrong-numbers", - "name": "Armstrong Numbers", - "uuid": "77c5c7e6-265a-4f1a-9bc4-851f8f825420", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "math" - ] - }, - { - "slug": "flatten-array", - "name": "Flatten Array", - "uuid": "2df8ed82-2a04-4112-a17b-7813bcdc0e84", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "arrays", - "recursion" - ] - }, - { - "slug": "phone-number", - "name": "Phone Number", - "uuid": "b68665d5-14ef-4351-ac4a-c28a80c27b3d", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "conditionals", - "regular_expressions", - "strings", - "text_formatting", - "transforming" - ] - }, - { - "slug": "grains", - "name": "Grains", - "uuid": "22519f53-4516-43bc-915e-07d58e48f617", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "bitwise_operations", - "math" - ] - }, - { - "slug": "resistor-color-trio", - "name": "Resistor Color Trio", - "uuid": "2df14b68-75c8-4984-8ae2-ecd2cb7ed1d4", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "loops" - ] - }, - { - "slug": "saddle-points", - "name": "Saddle Points", - "uuid": "38bb4ac6-a5ec-4448-8b86-cdaff13a8be3", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "arrays", - "integers", - "matrices", - "searching" - ] - }, - { - "slug": "etl", - "name": "Etl", - "uuid": "0d66f3db-69a4-44b9-80be-9366f8b189ec", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "loops", - "maps", - "transforming" - ] - }, - { - "slug": "nucleotide-count", - "name": "Nucleotide Count", - "uuid": "8ad2bffd-1d79-4e1f-8ef3-ece0214d2804", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "maps", - "parsing", - "strings" - ] - }, - { - "slug": "pythagorean-triplet", - "name": "Pythagorean Triplet", - "uuid": "43aad536-0e24-464c-9554-cbc2699d0543", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "algorithms", - "math" - ] - }, - { - "slug": "collatz-conjecture", - "name": "Collatz Conjecture", - "uuid": "af961c87-341c-4dd3-a1eb-272501b9b0e4", - "prerequisites": [], - "difficulty": 1, - "topics": [ - "conditionals", - "control_flow_loops", - "integers", - "math" - ] - }, - { - "slug": "sieve", - "name": "Sieve", - "uuid": "80f9af5a-ea29-4937-9333-b4494aaf2446", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "algorithms", - "integers", - "loops", - "math", - "sorting" - ] - }, - { - "slug": "proverb", - "name": "Proverb", - "uuid": "3c5193ab-6471-4be2-9d24-1d2b51ad822a", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "arrays", - "loops", - "strings" - ] - }, - { - "slug": "palindrome-products", - "name": "Palindrome Products", - "uuid": "abd68340-91b9-48c1-8567-79822bb2165c", - "prerequisites": [], - "difficulty": 6, - "topics": [ - "algorithms", - "math" - ] - }, - { - "slug": "accumulate", - "name": "Accumulate", - "uuid": "2c71fc3a-2c93-402b-b091-697b795ce3ba", - "prerequisites": [], - "difficulty": 1, - "topics": [ - "lists" - ] - }, - { - "slug": "bob", - "name": "Bob", - "uuid": "70fec82e-3038-468f-96ef-bfb48ce03ef3", - "prerequisites": [], - "difficulty": 2, - "topics": [ - "conditionals", - "strings" - ] - }, - { - "slug": "strain", - "name": "Strain", - "uuid": "ac0966a9-822b-45be-91d9-36f6706ea76f", - "prerequisites": [], - "difficulty": 2, - "topics": [ - "arrays", - "filtering", - "loops" - ] - }, - { - "slug": "nth-prime", - "name": "Nth Prime", - "uuid": "16baef71-6234-4928-a2d4-a19eb8e110b8", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "algorithms", - "integers", - "math" - ] - }, - { - "slug": "perfect-numbers", - "name": "Perfect Numbers", - "uuid": "76ad732a-6e58-403b-ac65-9091d355241f", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "algorithms", - "filtering", - "integers", - "math" - ] - }, - { - "slug": "alphametics", - "name": "Alphametics", - "uuid": "2323a2a5-c181-4c1e-9c5f-f6b92b2de511", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "algorithms", - "arrays", - "searching" - ] - }, - { - "slug": "binary-search", - "name": "Binary Search", - "uuid": "b1ba445d-4908-4922-acc0-de3a0ec92c53", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "algorithms", - "arrays", - "searching", - "sorting" - ] - }, - { - "slug": "two-bucket", - "name": "Two Bucket", - "uuid": "e5a2d445-437d-46a8-889b-fbcd62c70fa9", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "algorithms", - "conditionals", - "searching" - ] - }, - { - "slug": "matching-brackets", - "name": "Matching Brackets", - "uuid": "26f6e297-7980-4472-8ce7-157b62b0ff40", - "prerequisites": [], - "difficulty": 7, - "topics": [ - "parsing", - "strings" - ] - }, - { - "slug": "all-your-base", - "name": "All Your Base", - "uuid": "3ce4bd3e-0380-498a-8d0a-b79cf3fedc10", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "integers", - "math", - "transforming" - ] - }, - { - "slug": "scale-generator", - "name": "Scale Generator", - "uuid": "4134d491-8ec5-480b-aa61-37a02689db1f", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "pattern_matching", - "strings" - ] - }, - { - "slug": "allergies", - "name": "Allergies", - "uuid": "b306bdaa-438e-46a2-ba54-82cb2c0be882", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "bitwise_operations", - "enumeration" - ] - }, - { - "slug": "rail-fence-cipher", - "name": "Rail Fence Cipher", - "uuid": "64196fe5-2270-4113-a614-fbfbb6d00f2b", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "algorithms", - "cryptography", - "loops", - "sorting", - "strings", - "text_formatting", - "transforming" - ] - }, - { - "slug": "run-length-encoding", - "name": "Run Length Encoding", - "uuid": "9d6a8c89-41c1-4c4e-b24c-476ba0dfa5f9", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "parsing", - "strings", - "transforming" - ] - }, - { - "slug": "minesweeper", - "name": "Minesweeper", - "uuid": "9d6808fb-d367-4df9-a1f0-47ff83b75544", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "arrays", - "games", - "loops", - "matrices", - "transforming" - ] - }, - { - "slug": "robot-simulator", - "name": "Robot Simulator", - "uuid": "724e6a6e-2e6e-45a9-ab0e-0d8d50a06085", - "prerequisites": [], - "difficulty": 6, - "topics": [ - "concurrency", - "loops", - "sequences", - "strings", - "structs" - ] - }, - { - "slug": "beer-song", - "name": "Beer Song", - "uuid": "50c34698-7767-42b3-962f-21c735e49787", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "loops", - "strings", - "text_formatting" - ] - }, - { - "slug": "protein-translation", - "name": "Protein Translation", - "uuid": "00c6f623-2e54-4f90-ae3f-07e493f93c7c", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "filtering", - "maps", - "sequences" - ] - }, - { - "slug": "wordy", - "name": "Wordy", - "uuid": "cb58e4cf-e3af-469c-9f2d-02557b9f61ed", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "conditionals", - "integers", - "parsing", - "strings", - "type_conversion" - ] - }, - { - "slug": "secret-handshake", - "name": "Secret Handshake", - "uuid": "c1ebad1b-d5aa-465a-b5ef-9e717ab5db9e", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "arrays", - "bitwise_operations", - "integers" - ] - }, - { - "slug": "atbash-cipher", - "name": "Atbash Cipher", - "uuid": "1e737640-9785-4a47-866a-46298104d891", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "algorithms", - "cryptography", - "strings", - "transforming" - ] - }, - { - "slug": "crypto-square", - "name": "Crypto Square", - "uuid": "86f8e33d-31b7-43e3-8ea3-2e391133704a", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "cryptography", - "filtering", - "strings", - "text_formatting", - "transforming" - ] - }, - { - "slug": "list-ops", - "name": "List Ops", - "uuid": "f62e8acb-8370-46e1-ad7f-a6a2644f8602", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "functional_programming", - "lists", - "recursion", - "type_conversion" - ] - }, - { - "slug": "robot-name", - "name": "Robot Name", - "uuid": "76a0fd0a-cc65-4be3-acc8-7348bb67ad5a", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "randomness" - ] - }, - { - "slug": "simple-cipher", - "name": "Simple Cipher", - "uuid": "29c66e8a-b1b0-4bbd-be7b-9979ff51ba8f", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "algorithms", - "cryptography", - "interfaces", - "strings", - "transforming" - ] - }, - { - "slug": "dominoes", - "name": "Dominoes", - "uuid": "705f3eb6-55a9-476c-b3f2-e9f3cb0bbe37", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "algorithms", - "arrays", - "searching" - ] - }, - { - "slug": "pig-latin", - "name": "Pig Latin", - "uuid": "efc0e498-891a-4e91-a6aa-fae635573a83", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "conditionals", - "strings", - "transforming" - ] - }, - { - "slug": "simple-linked-list", - "name": "Simple Linked List", - "uuid": "fa7b91c2-842c-42c8-bdf9-00bb3e71a7f5", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "arrays", - "loops" - ] - }, - { - "slug": "binary-search-tree", - "name": "Binary Search Tree", - "uuid": "0e05bfcf-17ae-4884-803a-fa1428bc1702", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "algorithms", - "recursion", - "searching", - "sorting", - "structs", - "trees" - ] - }, - { - "slug": "change", - "name": "Change", - "uuid": "dc6c3e44-1027-4d53-9653-ba06824f8bcf", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "algorithms", - "arrays", - "loops", - "searching" - ] - }, - { - "slug": "circular-buffer", - "name": "Circular Buffer", - "uuid": "f3419fe3-a5f5-4bc9-bc40-49f450b8981e", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "queues", - "structs" - ] - }, - { - "slug": "grade-school", - "name": "Grade School", - "uuid": "4460742c-2beb-48d7-94e6-72ff13c68c71", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "lists", - "sorting", - "structs" - ] - }, - { - "slug": "roman-numerals", - "name": "Roman Numerals", - "uuid": "b7ca9519-c33b-418b-a4ef-858a3d4d6855", - "prerequisites": [], - "difficulty": 2, - "topics": [ - "numbers", - "transforming" - ] - }, - { - "slug": "rotational-cipher", - "name": "Rotational Cipher", - "uuid": "af5ccf14-eff2-4dc6-b1db-e209cddca62a", - "prerequisites": [], - "difficulty": 2, - "topics": [ - "cryptography", - "integers", - "strings" - ] - }, - { - "slug": "affine-cipher", - "name": "Affine Cipher", - "uuid": "d1267415-aff5-411d-b267-49a4a2c8fda2", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "cryptography", - "math", - "strings" - ] - }, - { - "slug": "kindergarten-garden", - "name": "Kindergarten Garden", - "uuid": "04bde625-e363-4d8b-880f-db7bf86286eb", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "parsing", - "records", - "searching", - "strings", - "structs" - ] - }, - { - "slug": "largest-series-product", - "name": "Largest Series Product", - "uuid": "7cb55328-1b11-4544-94c0-945444d9a6a4", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "algorithms", - "integers", - "math", - "sequences" - ] - }, - { - "slug": "prime-factors", - "name": "Prime Factors", - "uuid": "a18daa31-88d3-45ba-84ca-f1d52fe23a79", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "algorithms", - "integers", - "math" - ] - }, - { - "slug": "custom-set", - "name": "Custom Set", - "uuid": "4f74b3cd-f995-4b8c-9b57-23f073261d0e", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "filtering", - "loops", - "sets" - ] - }, - { - "slug": "house", - "name": "House", - "uuid": "df5d771a-e57b-4a96-8a29-9bd4ce7f88d2", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "recursion", - "strings", - "text_formatting" - ] - }, - { - "slug": "linked-list", - "name": "Linked List", - "uuid": "92c9aafc-791d-4aaf-a136-9bee14f6ff95", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "data_structure", - "pointer" - ] - }, - { - "slug": "poker", - "name": "Poker", - "uuid": "9a59ba44-34f5-410b-a1e6-9a5c47c52d9e", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "equality", - "games", - "parsing", - "pattern_matching", - "sequences", - "strings" - ] - }, - { - "slug": "isbn-verifier", - "name": "Isbn Verifier", - "uuid": "a0aac827-8f7a-4065-9d05-a57009f5668d", - "prerequisites": [], - "difficulty": 2, - "topics": [ - "arrays" - ] - }, - { - "slug": "complex-numbers", - "name": "Complex Numbers", - "uuid": "d75bd7c0-52c5-44f2-a046-f63cb332425f", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "math" - ] - }, - { - "slug": "meetup", - "name": "Meetup", - "uuid": "8120e133-9561-4f82-8081-10c19f7f6ba3", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "dates", - "time", - "transforming", - "type_conversion" - ] - }, - { - "slug": "diamond", - "name": "Diamond", - "uuid": "c55c75fb-6140-4042-967a-39c75b7781bd", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "algorithms", - "conditionals", - "loops", - "strings", - "text_formatting" - ] - }, - { - "slug": "bowling", - "name": "Bowling", - "uuid": "051f0825-8357-4ca6-b24f-40a373deac19", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "algorithms", - "arrays", - "conditionals" - ] - }, - { - "slug": "ocr-numbers", - "name": "Ocr Numbers", - "uuid": "dd13bb29-589c-497d-9580-3f288f353fb2", - "prerequisites": [], - "difficulty": 7, - "topics": [ - "parsing", - "pattern_recognition" - ] - }, - { - "slug": "say", - "name": "Say", - "uuid": "2a410923-6445-41fc-9cf3-a60209e1c1c2", - "prerequisites": [], - "difficulty": 7, - "topics": [ - "numbers", - "strings", - "text_formatting", - "transforming" - ] - }, - { - "slug": "zipper", - "name": "Zipper", - "uuid": "239b8e79-2983-4ce0-9dda-9bb999e79d11", - "prerequisites": [], - "difficulty": 7, - "topics": [ - "data_structures" - ] - }, - { - "slug": "grep", - "name": "Grep", - "uuid": "99485900-5d16-4848-af1c-2f1a62ad35ab", - "prerequisites": [], - "difficulty": 8, - "topics": [ - "files", - "parsing", - "pattern_matching", - "regular_expressions", - "strings", - "text_formatting" - ] - }, - { - "slug": "food-chain", - "name": "Food Chain", - "uuid": "6f0919eb-2160-4cca-8504-286acc2ae9c8", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "conditionals", - "loops", - "recursion", - "strings", - "text_formatting" - ] - }, - { - "slug": "pascals-triangle", - "name": "Pascals Triangle", - "uuid": "4ff8b056-f27d-4bdf-b7af-214448db4260", - "prerequisites": [], - "difficulty": 4, - "topics": [ - "algorithms", - "arrays", - "math", - "recursion" - ] - }, - { - "slug": "queen-attack", - "name": "Queen Attack", - "uuid": "2ce9b158-e730-4c86-8639-bd08af9f80f4", - "prerequisites": [], - "difficulty": 5, - "topics": [ - "booleans", - "errors", - "games", - "logic" - ] - }, - { - "slug": "book-store", - "name": "Book Store", - "uuid": "0ec96460-08be-49a0-973a-4336f21b763c", - "prerequisites": [], - "difficulty": 8, - "topics": [ - "algorithms", - "floating_point_numbers", - "integers", - "lists" - ] - }, - { - "slug": "connect", - "name": "Connect", - "uuid": "538a6768-bae5-437c-9cdf-765d73a79643", - "prerequisites": [], - "difficulty": 9, - "topics": [ - "arrays", - "games", - "graphs", - "loops", - "searching" - ] - }, - { - "slug": "binary", - "name": "Binary", - "uuid": "43bc27ed-d2fa-4173-8665-4459b71c9a3a", - "prerequisites": [], - "difficulty": 0, - "topics": null, - "status": "deprecated" - }, - { - "slug": "hexadecimal", - "name": "Hexadecimal", - "uuid": "6984cc14-91f8-47a7-b7e2-4b210a5dbc5c", - "prerequisites": [], - "difficulty": 0, - "topics": null, - "status": "deprecated" - }, - { - "slug": "octal", - "name": "Octal", - "uuid": "cae4e000-3aac-41f7-b727-f9cce12d058d", - "prerequisites": [], - "difficulty": 0, - "topics": null, - "status": "deprecated" - }, - { - "slug": "point-mutations", - "name": "Point Mutations", - "uuid": "89bd3d71-000f-4cd9-9a84-ad1b22ddbd33", - "prerequisites": [], - "difficulty": 0, - "topics": null, - "status": "deprecated" - }, - { - "slug": "trinary", - "name": "Trinary", - "uuid": "f6735416-4be6-4eb8-b6b9-cb61671ce25e", - "prerequisites": [], - "difficulty": 0, - "topics": null, - "status": "deprecated" - }, - { - "slug": "microwave", - "name": "Microwave", - "uuid": "b960d0fe-a07f-11ea-bb37-0242ac130002", - "prerequisites": [], - "difficulty": 2, - "topics": [ - "math", - "strings", - "interpolation" - ] - }, - { - "slug": "darts", - "name": "Darts", - "uuid": "15b73808-78a4-4854-b7cf-82a478107024", - "prerequisites": [], - "difficulty": 3, - "topics": [ - "math", - "geometry" - ] - } - ] + "exercises": { + "practice": [ + { + "slug": "hello-world", + "name": "Hello World", + "uuid": "4fe19484-4414-471b-a106-73c776c61388", + "prerequisites": [], + "difficulty": 1, + "topics": [ + "strings" + ] + }, + { + "slug": "two-fer", + "name": "Two Fer", + "uuid": "1304b188-6d08-4361-be40-c6b1b88e5e54", + "prerequisites": [], + "difficulty": 1, + "topics": [ + "conditionals", + "strings" + ] + }, + { + "slug": "resistor-color-duo", + "name": "Resistor Color Duo", + "uuid": "57b0c57e-26a5-4ccf-aaf2-2fefddd918c1", + "prerequisites": [], + "difficulty": 1, + "topics": [ + "array", + "loops" + ] + }, + { + "slug": "acronym", + "name": "Acronym", + "uuid": "74468206-68a2-4efb-8caa-782634674c7f", + "prerequisites": [], + "difficulty": 1, + "topics": [ + "regular_expressions", + "strings", + "transforming" + ] + }, + { + "slug": "high-scores", + "name": "High Scores", + "uuid": "9124339c-94fb-46eb-aad2-25944214799d", + "prerequisites": [], + "difficulty": 2, + "topics": [ + "arrays" + ] + }, + { + "slug": "matrix", + "name": "Matrix", + "uuid": "3de21c18-a533-4150-8a73-49df8fcb8c61", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "arrays", + "exception_handling", + "matrices", + "strings", + "type_conversion" + ] + }, + { + "slug": "series", + "name": "Series", + "uuid": "2de036e4-576d-47fc-bb03-4ed1612e79da", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "arrays", + "enumerable", + "loops" + ] + }, + { + "slug": "word-count", + "name": "Word Count", + "uuid": "e9d29769-8d4d-4159-8d6f-762db5339707", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "enumerable", + "hash", + "loops" + ] + }, + { + "slug": "hamming", + "name": "Hamming", + "uuid": "d33dec8a-e2b4-40bc-8be9-3f49de084d43", + "prerequisites": [], + "difficulty": 1, + "topics": [ + "equality", + "loops", + "strings" + ] + }, + { + "slug": "raindrops", + "name": "Raindrops", + "uuid": "efad2cea-1e0b-4fb8-a452-a8e91be73638", + "prerequisites": [], + "difficulty": 1, + "topics": [ + "conditionals", + "filtering", + "strings" + ] + }, + { + "slug": "isogram", + "name": "Isogram", + "uuid": "a79eb8cd-d2db-48f5-a7dc-055039dcee62", + "prerequisites": [], + "difficulty": 2, + "topics": [ + "regular_expressions", + "sequences", + "strings" + ] + }, + { + "slug": "scrabble-score", + "name": "Scrabble Score", + "uuid": "d934ebce-9ac3-4a41-bcb8-d70480170438", + "prerequisites": [], + "difficulty": 2, + "topics": [ + "loops", + "maps", + "strings" + ] + }, + { + "slug": "luhn", + "name": "Luhn", + "uuid": "bee97539-b8c1-460e-aa14-9336008df2b6", + "prerequisites": [], + "difficulty": 2, + "topics": [ + "algorithms", + "integers", + "strings" + ] + }, + { + "slug": "clock", + "name": "Clock", + "uuid": "f95ebf09-0f32-4e60-867d-60cb81dd9a62", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "equality", + "text_formatting", + "time" + ] + }, + { + "slug": "twelve-days", + "name": "Twelve Days", + "uuid": "eeb64dda-b79f-4920-8fa3-04810e8d37ab", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "algorithms", + "pattern_recognition", + "sequences", + "strings", + "text_formatting" + ] + }, + { + "slug": "tournament", + "name": "Tournament", + "uuid": "486becee-9d85-4139-ab89-db254d385ade", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "integers", + "parsing", + "records", + "sorting", + "strings", + "text_formatting", + "transforming" + ] + }, + { + "slug": "gigasecond", + "name": "Gigasecond", + "uuid": "0fb594a1-193b-4ccf-8de2-eb6a81708b29", + "prerequisites": [], + "difficulty": 1, + "topics": [ + "time" + ] + }, + { + "slug": "resistor-color", + "name": "Resistor Color", + "uuid": "685634dd-0b38-40bc-b0ad-e8aa2904035f", + "prerequisites": [], + "difficulty": 1, + "topics": [ + "arrays" + ] + }, + { + "slug": "rna-transcription", + "name": "Rna Transcription", + "uuid": "41f66d2a-1883-4a2c-875f-663c46fa88aa", + "prerequisites": [], + "difficulty": 2, + "topics": [ + "maps", + "transforming" + ] + }, + { + "slug": "leap", + "name": "Leap", + "uuid": "06eaa2dd-dc80-4d38-b10d-11174183b0b6", + "prerequisites": [], + "difficulty": 1, + "topics": [ + "booleans", + "conditionals", + "integers", + "logic" + ] + }, + { + "slug": "pangram", + "name": "Pangram", + "uuid": "fcf07149-b2cb-4042-90e6-fb3350e0fdf6", + "prerequisites": [], + "difficulty": 2, + "topics": [ + "loops", + "strings" + ] + }, + { + "slug": "space-age", + "name": "Space Age", + "uuid": "c971a2b5-ccd4-4e55-9fc7-33e991bc0676", + "prerequisites": [], + "difficulty": 2, + "topics": [ + "floating_point_numbers", + "if_else_statements" + ] + }, + { + "slug": "triangle", + "name": "Triangle", + "uuid": "5c797eb2-155d-47ca-8f85-2ba5803f9713", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "booleans", + "conditionals", + "logic" + ] + }, + { + "slug": "difference-of-squares", + "name": "Difference Of Squares", + "uuid": "f1e4ee0c-8718-43f2-90a5-fb1e915288da", + "prerequisites": [], + "difficulty": 2, + "topics": [ + "algorithms", + "math" + ] + }, + { + "slug": "anagram", + "name": "Anagram", + "uuid": "36df18ba-580d-4982-984e-ba50eb1f8c0b", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "filtering", + "parsing", + "sorting", + "strings" + ] + }, + { + "slug": "sum-of-multiples", + "name": "Sum Of Multiples", + "uuid": "4fc25295-5d6a-4d13-9b87-064167d8980e", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "loops", + "math" + ] + }, + { + "slug": "transpose", + "name": "Transpose", + "uuid": "4a6bc7d3-5d3b-4ad8-96ae-783e17af7c32", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "loops", + "strings", + "transforming" + ] + }, + { + "slug": "armstrong-numbers", + "name": "Armstrong Numbers", + "uuid": "77c5c7e6-265a-4f1a-9bc4-851f8f825420", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "math" + ] + }, + { + "slug": "flatten-array", + "name": "Flatten Array", + "uuid": "2df8ed82-2a04-4112-a17b-7813bcdc0e84", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "arrays", + "recursion" + ] + }, + { + "slug": "phone-number", + "name": "Phone Number", + "uuid": "b68665d5-14ef-4351-ac4a-c28a80c27b3d", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "conditionals", + "regular_expressions", + "strings", + "text_formatting", + "transforming" + ] + }, + { + "slug": "grains", + "name": "Grains", + "uuid": "22519f53-4516-43bc-915e-07d58e48f617", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "bitwise_operations", + "math" + ] + }, + { + "slug": "resistor-color-trio", + "name": "Resistor Color Trio", + "uuid": "2df14b68-75c8-4984-8ae2-ecd2cb7ed1d4", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "loops" + ] + }, + { + "slug": "saddle-points", + "name": "Saddle Points", + "uuid": "38bb4ac6-a5ec-4448-8b86-cdaff13a8be3", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "arrays", + "integers", + "matrices", + "searching" + ] + }, + { + "slug": "etl", + "name": "Etl", + "uuid": "0d66f3db-69a4-44b9-80be-9366f8b189ec", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "loops", + "maps", + "transforming" + ] + }, + { + "slug": "nucleotide-count", + "name": "Nucleotide Count", + "uuid": "8ad2bffd-1d79-4e1f-8ef3-ece0214d2804", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "maps", + "parsing", + "strings" + ] + }, + { + "slug": "pythagorean-triplet", + "name": "Pythagorean Triplet", + "uuid": "43aad536-0e24-464c-9554-cbc2699d0543", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "algorithms", + "math" + ] + }, + { + "slug": "collatz-conjecture", + "name": "Collatz Conjecture", + "uuid": "af961c87-341c-4dd3-a1eb-272501b9b0e4", + "prerequisites": [], + "difficulty": 1, + "topics": [ + "conditionals", + "control_flow_loops", + "integers", + "math" + ] + }, + { + "slug": "sieve", + "name": "Sieve", + "uuid": "80f9af5a-ea29-4937-9333-b4494aaf2446", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "algorithms", + "integers", + "loops", + "math", + "sorting" + ] + }, + { + "slug": "proverb", + "name": "Proverb", + "uuid": "3c5193ab-6471-4be2-9d24-1d2b51ad822a", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "arrays", + "loops", + "strings" + ] + }, + { + "slug": "palindrome-products", + "name": "Palindrome Products", + "uuid": "abd68340-91b9-48c1-8567-79822bb2165c", + "prerequisites": [], + "difficulty": 6, + "topics": [ + "algorithms", + "math" + ] + }, + { + "slug": "accumulate", + "name": "Accumulate", + "uuid": "2c71fc3a-2c93-402b-b091-697b795ce3ba", + "prerequisites": [], + "difficulty": 1, + "topics": [ + "lists" + ] + }, + { + "slug": "bob", + "name": "Bob", + "uuid": "70fec82e-3038-468f-96ef-bfb48ce03ef3", + "prerequisites": [], + "difficulty": 2, + "topics": [ + "conditionals", + "strings" + ] + }, + { + "slug": "strain", + "name": "Strain", + "uuid": "ac0966a9-822b-45be-91d9-36f6706ea76f", + "prerequisites": [], + "difficulty": 2, + "topics": [ + "arrays", + "filtering", + "loops" + ] + }, + { + "slug": "nth-prime", + "name": "Nth Prime", + "uuid": "16baef71-6234-4928-a2d4-a19eb8e110b8", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "algorithms", + "integers", + "math" + ] + }, + { + "slug": "perfect-numbers", + "name": "Perfect Numbers", + "uuid": "76ad732a-6e58-403b-ac65-9091d355241f", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "algorithms", + "filtering", + "integers", + "math" + ] + }, + { + "slug": "alphametics", + "name": "Alphametics", + "uuid": "2323a2a5-c181-4c1e-9c5f-f6b92b2de511", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "algorithms", + "arrays", + "searching" + ] + }, + { + "slug": "binary-search", + "name": "Binary Search", + "uuid": "b1ba445d-4908-4922-acc0-de3a0ec92c53", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "algorithms", + "arrays", + "searching", + "sorting" + ] + }, + { + "slug": "two-bucket", + "name": "Two Bucket", + "uuid": "e5a2d445-437d-46a8-889b-fbcd62c70fa9", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "algorithms", + "conditionals", + "searching" + ] + }, + { + "slug": "matching-brackets", + "name": "Matching Brackets", + "uuid": "26f6e297-7980-4472-8ce7-157b62b0ff40", + "prerequisites": [], + "difficulty": 7, + "topics": [ + "parsing", + "strings" + ] + }, + { + "slug": "all-your-base", + "name": "All Your Base", + "uuid": "3ce4bd3e-0380-498a-8d0a-b79cf3fedc10", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "integers", + "math", + "transforming" + ] + }, + { + "slug": "scale-generator", + "name": "Scale Generator", + "uuid": "4134d491-8ec5-480b-aa61-37a02689db1f", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "pattern_matching", + "strings" + ] + }, + { + "slug": "allergies", + "name": "Allergies", + "uuid": "b306bdaa-438e-46a2-ba54-82cb2c0be882", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "bitwise_operations", + "enumeration" + ] + }, + { + "slug": "rail-fence-cipher", + "name": "Rail Fence Cipher", + "uuid": "64196fe5-2270-4113-a614-fbfbb6d00f2b", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "algorithms", + "cryptography", + "loops", + "sorting", + "strings", + "text_formatting", + "transforming" + ] + }, + { + "slug": "run-length-encoding", + "name": "Run Length Encoding", + "uuid": "9d6a8c89-41c1-4c4e-b24c-476ba0dfa5f9", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "parsing", + "strings", + "transforming" + ] + }, + { + "slug": "minesweeper", + "name": "Minesweeper", + "uuid": "9d6808fb-d367-4df9-a1f0-47ff83b75544", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "arrays", + "games", + "loops", + "matrices", + "transforming" + ] + }, + { + "slug": "robot-simulator", + "name": "Robot Simulator", + "uuid": "724e6a6e-2e6e-45a9-ab0e-0d8d50a06085", + "prerequisites": [], + "difficulty": 6, + "topics": [ + "concurrency", + "loops", + "sequences", + "strings", + "structs" + ] + }, + { + "slug": "beer-song", + "name": "Beer Song", + "uuid": "50c34698-7767-42b3-962f-21c735e49787", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "loops", + "strings", + "text_formatting" + ] + }, + { + "slug": "protein-translation", + "name": "Protein Translation", + "uuid": "00c6f623-2e54-4f90-ae3f-07e493f93c7c", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "filtering", + "maps", + "sequences" + ] + }, + { + "slug": "wordy", + "name": "Wordy", + "uuid": "cb58e4cf-e3af-469c-9f2d-02557b9f61ed", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "conditionals", + "integers", + "parsing", + "strings", + "type_conversion" + ] + }, + { + "slug": "secret-handshake", + "name": "Secret Handshake", + "uuid": "c1ebad1b-d5aa-465a-b5ef-9e717ab5db9e", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "arrays", + "bitwise_operations", + "integers" + ] + }, + { + "slug": "atbash-cipher", + "name": "Atbash Cipher", + "uuid": "1e737640-9785-4a47-866a-46298104d891", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "algorithms", + "cryptography", + "strings", + "transforming" + ] + }, + { + "slug": "crypto-square", + "name": "Crypto Square", + "uuid": "86f8e33d-31b7-43e3-8ea3-2e391133704a", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "cryptography", + "filtering", + "strings", + "text_formatting", + "transforming" + ] + }, + { + "slug": "list-ops", + "name": "List Ops", + "uuid": "f62e8acb-8370-46e1-ad7f-a6a2644f8602", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "functional_programming", + "lists", + "recursion", + "type_conversion" + ] + }, + { + "slug": "robot-name", + "name": "Robot Name", + "uuid": "76a0fd0a-cc65-4be3-acc8-7348bb67ad5a", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "randomness" + ] + }, + { + "slug": "simple-cipher", + "name": "Simple Cipher", + "uuid": "29c66e8a-b1b0-4bbd-be7b-9979ff51ba8f", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "algorithms", + "cryptography", + "interfaces", + "strings", + "transforming" + ] + }, + { + "slug": "dominoes", + "name": "Dominoes", + "uuid": "705f3eb6-55a9-476c-b3f2-e9f3cb0bbe37", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "algorithms", + "arrays", + "searching" + ] + }, + { + "slug": "pig-latin", + "name": "Pig Latin", + "uuid": "efc0e498-891a-4e91-a6aa-fae635573a83", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "conditionals", + "strings", + "transforming" + ] + }, + { + "slug": "simple-linked-list", + "name": "Simple Linked List", + "uuid": "fa7b91c2-842c-42c8-bdf9-00bb3e71a7f5", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "arrays", + "loops" + ] + }, + { + "slug": "binary-search-tree", + "name": "Binary Search Tree", + "uuid": "0e05bfcf-17ae-4884-803a-fa1428bc1702", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "algorithms", + "recursion", + "searching", + "sorting", + "structs", + "trees" + ] + }, + { + "slug": "change", + "name": "Change", + "uuid": "dc6c3e44-1027-4d53-9653-ba06824f8bcf", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "algorithms", + "arrays", + "loops", + "searching" + ] + }, + { + "slug": "circular-buffer", + "name": "Circular Buffer", + "uuid": "f3419fe3-a5f5-4bc9-bc40-49f450b8981e", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "queues", + "structs" + ] + }, + { + "slug": "grade-school", + "name": "Grade School", + "uuid": "4460742c-2beb-48d7-94e6-72ff13c68c71", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "lists", + "sorting", + "structs" + ] + }, + { + "slug": "roman-numerals", + "name": "Roman Numerals", + "uuid": "b7ca9519-c33b-418b-a4ef-858a3d4d6855", + "prerequisites": [], + "difficulty": 2, + "topics": [ + "numbers", + "transforming" + ] + }, + { + "slug": "rotational-cipher", + "name": "Rotational Cipher", + "uuid": "af5ccf14-eff2-4dc6-b1db-e209cddca62a", + "prerequisites": [], + "difficulty": 2, + "topics": [ + "cryptography", + "integers", + "strings" + ] + }, + { + "slug": "affine-cipher", + "name": "Affine Cipher", + "uuid": "d1267415-aff5-411d-b267-49a4a2c8fda2", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "cryptography", + "math", + "strings" + ] + }, + { + "slug": "kindergarten-garden", + "name": "Kindergarten Garden", + "uuid": "04bde625-e363-4d8b-880f-db7bf86286eb", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "parsing", + "records", + "searching", + "strings", + "structs" + ] + }, + { + "slug": "largest-series-product", + "name": "Largest Series Product", + "uuid": "7cb55328-1b11-4544-94c0-945444d9a6a4", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "algorithms", + "integers", + "math", + "sequences" + ] + }, + { + "slug": "prime-factors", + "name": "Prime Factors", + "uuid": "a18daa31-88d3-45ba-84ca-f1d52fe23a79", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "algorithms", + "integers", + "math" + ] + }, + { + "slug": "custom-set", + "name": "Custom Set", + "uuid": "4f74b3cd-f995-4b8c-9b57-23f073261d0e", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "filtering", + "loops", + "sets" + ] + }, + { + "slug": "house", + "name": "House", + "uuid": "df5d771a-e57b-4a96-8a29-9bd4ce7f88d2", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "recursion", + "strings", + "text_formatting" + ] + }, + { + "slug": "linked-list", + "name": "Linked List", + "uuid": "92c9aafc-791d-4aaf-a136-9bee14f6ff95", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "data_structure", + "pointer" + ] + }, + { + "slug": "poker", + "name": "Poker", + "uuid": "9a59ba44-34f5-410b-a1e6-9a5c47c52d9e", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "equality", + "games", + "parsing", + "pattern_matching", + "sequences", + "strings" + ] + }, + { + "slug": "isbn-verifier", + "name": "Isbn Verifier", + "uuid": "a0aac827-8f7a-4065-9d05-a57009f5668d", + "prerequisites": [], + "difficulty": 2, + "topics": [ + "arrays" + ] + }, + { + "slug": "complex-numbers", + "name": "Complex Numbers", + "uuid": "d75bd7c0-52c5-44f2-a046-f63cb332425f", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "math" + ] + }, + { + "slug": "meetup", + "name": "Meetup", + "uuid": "8120e133-9561-4f82-8081-10c19f7f6ba3", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "dates", + "time", + "transforming", + "type_conversion" + ] + }, + { + "slug": "diamond", + "name": "Diamond", + "uuid": "c55c75fb-6140-4042-967a-39c75b7781bd", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "algorithms", + "conditionals", + "loops", + "strings", + "text_formatting" + ] + }, + { + "slug": "bowling", + "name": "Bowling", + "uuid": "051f0825-8357-4ca6-b24f-40a373deac19", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "algorithms", + "arrays", + "conditionals" + ] + }, + { + "slug": "ocr-numbers", + "name": "Ocr Numbers", + "uuid": "dd13bb29-589c-497d-9580-3f288f353fb2", + "prerequisites": [], + "difficulty": 7, + "topics": [ + "parsing", + "pattern_recognition" + ] + }, + { + "slug": "say", + "name": "Say", + "uuid": "2a410923-6445-41fc-9cf3-a60209e1c1c2", + "prerequisites": [], + "difficulty": 7, + "topics": [ + "numbers", + "strings", + "text_formatting", + "transforming" + ] + }, + { + "slug": "zipper", + "name": "Zipper", + "uuid": "239b8e79-2983-4ce0-9dda-9bb999e79d11", + "prerequisites": [], + "difficulty": 7, + "topics": [ + "data_structures" + ] + }, + { + "slug": "grep", + "name": "Grep", + "uuid": "99485900-5d16-4848-af1c-2f1a62ad35ab", + "prerequisites": [], + "difficulty": 8, + "topics": [ + "files", + "parsing", + "pattern_matching", + "regular_expressions", + "strings", + "text_formatting" + ] + }, + { + "slug": "food-chain", + "name": "Food Chain", + "uuid": "6f0919eb-2160-4cca-8504-286acc2ae9c8", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "conditionals", + "loops", + "recursion", + "strings", + "text_formatting" + ] + }, + { + "slug": "pascals-triangle", + "name": "Pascals Triangle", + "uuid": "4ff8b056-f27d-4bdf-b7af-214448db4260", + "prerequisites": [], + "difficulty": 4, + "topics": [ + "algorithms", + "arrays", + "math", + "recursion" + ] + }, + { + "slug": "queen-attack", + "name": "Queen Attack", + "uuid": "2ce9b158-e730-4c86-8639-bd08af9f80f4", + "prerequisites": [], + "difficulty": 5, + "topics": [ + "booleans", + "errors", + "games", + "logic" + ] + }, + { + "slug": "book-store", + "name": "Book Store", + "uuid": "0ec96460-08be-49a0-973a-4336f21b763c", + "prerequisites": [], + "difficulty": 8, + "topics": [ + "algorithms", + "floating_point_numbers", + "integers", + "lists" + ] + }, + { + "slug": "connect", + "name": "Connect", + "uuid": "538a6768-bae5-437c-9cdf-765d73a79643", + "prerequisites": [], + "difficulty": 9, + "topics": [ + "arrays", + "games", + "graphs", + "loops", + "searching" + ] + }, + { + "slug": "binary", + "name": "Binary", + "uuid": "43bc27ed-d2fa-4173-8665-4459b71c9a3a", + "prerequisites": [], + "difficulty": 0, + "topics": null, + "status": "deprecated" + }, + { + "slug": "hexadecimal", + "name": "Hexadecimal", + "uuid": "6984cc14-91f8-47a7-b7e2-4b210a5dbc5c", + "prerequisites": [], + "difficulty": 0, + "topics": null, + "status": "deprecated" + }, + { + "slug": "octal", + "name": "Octal", + "uuid": "cae4e000-3aac-41f7-b727-f9cce12d058d", + "prerequisites": [], + "difficulty": 0, + "topics": null, + "status": "deprecated" + }, + { + "slug": "point-mutations", + "name": "Point Mutations", + "uuid": "89bd3d71-000f-4cd9-9a84-ad1b22ddbd33", + "prerequisites": [], + "difficulty": 0, + "topics": null, + "status": "deprecated" + }, + { + "slug": "trinary", + "name": "Trinary", + "uuid": "f6735416-4be6-4eb8-b6b9-cb61671ce25e", + "prerequisites": [], + "difficulty": 0, + "topics": null, + "status": "deprecated" + }, + { + "slug": "microwave", + "name": "Microwave", + "uuid": "b960d0fe-a07f-11ea-bb37-0242ac130002", + "prerequisites": [], + "difficulty": 2, + "topics": [ + "math", + "strings", + "interpolation" + ] + }, + { + "slug": "darts", + "name": "Darts", + "uuid": "15b73808-78a4-4854-b7cf-82a478107024", + "prerequisites": [], + "difficulty": 3, + "topics": [ + "math", + "geometry" + ] + } + ] + } } From f4aee3e6240384fb6d1b6f7ce98e1d3104657e30 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:46 +0100 Subject: [PATCH 093/102] [v3] Add concept exercises to config.json --- config.json | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/config.json b/config.json index 24bd07cef7..bd3ce380d5 100644 --- a/config.json +++ b/config.json @@ -17,6 +17,83 @@ "indent_size": 2 }, "exercises": { + "concept": [ + { + "slug": "arrays", + "uuid": "4d271980-ab4b-11ea-bb37-0242ac130002", + "concepts": [ + "arrays" + ], + "prerequisites": [ + "classes", + "booleans", + "conditionals", + "blocks" + ] + }, + { + "slug": "strings", + "uuid": "e5476046-5289-11ea-8d77-2e728ce88125", + "concepts": [ + "strings" + ], + "prerequisites": [ + "basics" + ] + }, + { + "slug": "lasagna", + "uuid": "71ae39c4-7364-11ea-bc55-0242ac130003", + "concepts": [ + "basics" + ], + "prerequisites": [] + }, + { + "slug": "numbers", + "uuid": "d7108eb2-326c-446d-9140-228e0f220975", + "concepts": [ + "numbers", + "conditionals" + ], + "prerequisites": [ + "booleans" + ] + }, + { + "slug": "floating-point-numbers", + "uuid": "970d3f26-1891-40c7-9550-42d529f5780f", + "concepts": [ + "floating-point-numbers", + "loops" + ], + "prerequisites": [ + "numbers", + "conditionals" + ] + }, + { + "slug": "amusement_park_rides", + "uuid": "06ea7869-4907-454d-a5e5-9d5b71098b17", + "concepts": [ + "booleans" + ], + "prerequisites": [ + "instance-variables" + ] + }, + { + "slug": "instance-variables", + "uuid": "6905e411-ae01-46b6-a31c-8867b768856e", + "concepts": [ + "instance-variables", + "nil" + ], + "prerequisites": [ + "basics" + ] + } + ], "practice": [ { "slug": "hello-world", From c9dbfbd085939491ed8d6e5193d4f03660768937 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:46 +0100 Subject: [PATCH 094/102] [v3] Add wip status to concept exercises in config.json --- config.json | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/config.json b/config.json index bd3ce380d5..89ceba0351 100644 --- a/config.json +++ b/config.json @@ -29,7 +29,8 @@ "booleans", "conditionals", "blocks" - ] + ], + "status": "wip" }, { "slug": "strings", @@ -39,7 +40,8 @@ ], "prerequisites": [ "basics" - ] + ], + "status": "wip" }, { "slug": "lasagna", @@ -47,7 +49,8 @@ "concepts": [ "basics" ], - "prerequisites": [] + "prerequisites": [], + "status": "wip" }, { "slug": "numbers", @@ -58,7 +61,8 @@ ], "prerequisites": [ "booleans" - ] + ], + "status": "wip" }, { "slug": "floating-point-numbers", @@ -70,7 +74,8 @@ "prerequisites": [ "numbers", "conditionals" - ] + ], + "status": "wip" }, { "slug": "amusement_park_rides", @@ -80,7 +85,8 @@ ], "prerequisites": [ "instance-variables" - ] + ], + "status": "wip" }, { "slug": "instance-variables", @@ -91,7 +97,8 @@ ], "prerequisites": [ "basics" - ] + ], + "status": "wip" } ], "practice": [ From 3c7e2e4ccf7aa0e09937c6c3f8d945c98a09ed2a Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:47 +0100 Subject: [PATCH 095/102] [v3] Add concepts to config.json --- config.json | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/config.json b/config.json index 89ceba0351..cc0ae0403c 100644 --- a/config.json +++ b/config.json @@ -1339,5 +1339,79 @@ ] } ] - } + }, + "concepts": [ + { + "uuid": "7f2bf3a7-9771-48e8-bb6a-3022ca073a41", + "slug": "arrays", + "name": "Arrays", + "blurb": "TODO: add blurb for arrays concept" + }, + { + "uuid": "fe345fe6-229b-4b4b-a489-4ed3b77a1d7e", + "slug": "basics", + "name": "Basics", + "blurb": "TODO: add blurb for basics concept" + }, + { + "uuid": "bf57350d-9e18-4ec6-9341-e4d2c289724d", + "slug": "blocks", + "name": "Blocks", + "blurb": "TODO: add blurb for blocks concept" + }, + { + "uuid": "831b4db4-6b75-4a8d-a835-4c2555aacb61", + "slug": "booleans", + "name": "Booleans", + "blurb": "TODO: add blurb for booleans concept" + }, + { + "uuid": "acec3b2a-c1cc-4583-bd4b-9f7ae41acfb3", + "slug": "classes", + "name": "Classes", + "blurb": "TODO: add blurb for classes concept" + }, + { + "uuid": "dedd9182-66b7-4fbc-bf4b-ba6603edbfca", + "slug": "conditionals", + "name": "Conditionals", + "blurb": "TODO: add blurb for conditionals concept" + }, + { + "uuid": "01d61b5c-8f50-4b12-9fe0-0723e6f00999", + "slug": "floating-point-numbers", + "name": "Floating Point Numbers", + "blurb": "TODO: add blurb for floating-point-numbers concept" + }, + { + "uuid": "35001ed1-a7b9-4a80-a766-26725a29dc50", + "slug": "instance-variables", + "name": "Instance Variables", + "blurb": "TODO: add blurb for instance-variables concept" + }, + { + "uuid": "152d3976-dbcb-4a16-9f89-c61e0cdda4e5", + "slug": "loops", + "name": "Loops", + "blurb": "TODO: add blurb for loops concept" + }, + { + "uuid": "aa31cd95-54b2-4728-8fe3-2fdc244b3f53", + "slug": "nil", + "name": "Nil", + "blurb": "TODO: add blurb for nil concept" + }, + { + "uuid": "162721bd-3d64-43ff-889e-6fb2eac75709", + "slug": "numbers", + "name": "Numbers", + "blurb": "TODO: add blurb for numbers concept" + }, + { + "uuid": "3b1da281-7099-4c93-a109-178fc9436d68", + "slug": "strings", + "name": "Strings", + "blurb": "TODO: add blurb for strings concept" + } + ] } From 4f875102a2fc80476fd601f2ff20d7566748af6b Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:47 +0100 Subject: [PATCH 096/102] [v3] Add key features to config.json --- config.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config.json b/config.json index cc0ae0403c..9f573e1ebb 100644 --- a/config.json +++ b/config.json @@ -1413,5 +1413,6 @@ "name": "Strings", "blurb": "TODO: add blurb for strings concept" } - ] + ], + "key_features": [] } From 25e01533e8ef0dd46795d9662e855647838ea51e Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:47 +0100 Subject: [PATCH 097/102] [v3] Add tags to config.json --- config.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config.json b/config.json index 9f573e1ebb..5b905fb43f 100644 --- a/config.json +++ b/config.json @@ -1414,5 +1414,6 @@ "blurb": "TODO: add blurb for strings concept" } ], - "key_features": [] + "key_features": [], + "tags": [] } From 57d0b71b6ebb7ce9ce31cb36a66033d2f478f969 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:47 +0100 Subject: [PATCH 098/102] [v3] Use main branch for Exercism GitHub Actions --- .github/workflows/configlet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/configlet.yml b/.github/workflows/configlet.yml index 06c076e089..d25e20f506 100644 --- a/.github/workflows/configlet.yml +++ b/.github/workflows/configlet.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v2 - name: Fetch configlet - uses: exercism/github-actions/configlet-ci@master + uses: exercism/github-actions/configlet-ci@main - name: Configlet Linter run: configlet lint . From d3d8755cb7c74a51f9b65dcc4e21f00026f1eaad Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:47 +0100 Subject: [PATCH 099/102] [v3] Update fetch-configlet script to work with configlet v3 --- bin/fetch-configlet | 70 ++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/bin/fetch-configlet b/bin/fetch-configlet index 915ee034d4..43f1c83cee 100755 --- a/bin/fetch-configlet +++ b/bin/fetch-configlet @@ -1,52 +1,58 @@ -#!/bin/bash +#!/usr/bin/env bash set -eo pipefail readonly LATEST='https://api.github.com/repos/exercism/configlet/releases/latest' case "$(uname)" in - (Darwin*) OS='mac' ;; - (Linux*) OS='linux' ;; - (Windows*) OS='windows' ;; - (MINGW*) OS='windows' ;; - (MSYS_NT-*) OS='windows' ;; - (*) OS='linux' ;; + Darwin*) os='mac' ;; + Linux*) os='linux' ;; + Windows*) os='windows' ;; + MINGW*) os='windows' ;; + MSYS_NT-*) os='windows' ;; + *) os='linux' ;; esac -case "$OS" in - (windows*) EXT='zip' ;; - (*) EXT='tgz' ;; +case "${os}" in + windows*) ext='zip' ;; + *) ext='tgz' ;; esac case "$(uname -m)" in - (*64*) ARCH='64bit' ;; - (*686*) ARCH='32bit' ;; - (*386*) ARCH='32bit' ;; - (*) ARCH='64bit' ;; + *64*) arch='64bit' ;; + *686*) arch='32bit' ;; + *386*) arch='32bit' ;; + *) arch='64bit' ;; esac -if [ -z "${GITHUB_TOKEN}" ] -then - HEADER='' -else - HEADER="authorization: Bearer ${GITHUB_TOKEN}" +curlopts=( + --silent + --show-error + --fail + --location + --retry 3 +) + +if [[ -n "${GITHUB_TOKEN}" ]]; then + curlopts+=(--header "authorization: Bearer ${GITHUB_TOKEN}") fi -FILENAME="configlet-${OS}-${ARCH}.${EXT}" +suffix="${os}-${arch}.${ext}" -get_url () { - curl --header "$HEADER" -s "$LATEST" | - awk -v filename=$FILENAME '$1 ~ /browser_download_url/ && $2 ~ filename { print $2 }' | - tr -d '"' +get_download_url() { + curl "${curlopts[@]}" --header 'Accept: application/vnd.github.v3+json' "${LATEST}" | + grep "\"browser_download_url\": \".*/download/.*/configlet.*${suffix}\"$" | + cut -d'"' -f4 } -URL=$(get_url) +download_url="$(get_download_url)" +output_dir="bin" +output_path="${output_dir}/latest-configlet.${ext}" +curl "${curlopts[@]}" --output "${output_path}" "${download_url}" -case "$EXT" in - (*zip) - curl --header "$HEADER" -s --location "$URL" -o bin/latest-configlet.zip - unzip bin/latest-configlet.zip -d bin/ - rm bin/latest-configlet.zip - ;; - (*) curl --header "$HEADER" -s --location "$URL" | tar xz -C bin/ ;; +case "${ext}" in + *zip) unzip "${output_path}" -d "${output_dir}" ;; + *) tar xzf "${output_path}" -C "${output_dir}" ;; esac + +rm -f "${output_path}" From d2bdbeb20e50e25c94758e85f1d1dff7cde0f475 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:47 +0100 Subject: [PATCH 100/102] [v3] Add dependabot to keep GHA dependencies up-to-date --- .github/dependabot.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..ed8f4a432b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 + +updates: + + # Keep dependencies for GitHub Actions up-to-date + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'daily' From 6a33925c7e0719842fdab2a1cd7446b0fa0b59db Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 15:54:48 +0100 Subject: [PATCH 101/102] [v3] Convert relative v3 links to absolute links --- README.md | 2 +- concepts/basics/introduction.md | 2 +- exercises/concept/lasagna/.docs/introduction.md | 2 +- reference/implementing-a-concept-exercise.md | 10 +++++----- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f685bd0e56..92d1a3a860 100644 --- a/README.md +++ b/README.md @@ -213,7 +213,7 @@ In the first case, the changes need to be made to the `canonical-data.json` file for the exercise, which lives in the problem-specifications repository. ``` -../problem-specifications/exercises// +https://github.com/exercism/v3/blob/main/problem-specifications/exercises// ├── canonical-data.json ├── description.md └── metadata.yml diff --git a/concepts/basics/introduction.md b/concepts/basics/introduction.md index 754cdc9a2e..537bc457d9 100644 --- a/concepts/basics/introduction.md +++ b/concepts/basics/introduction.md @@ -51,5 +51,5 @@ calc.multiply(num1: 2, num_2: 5) ``` [object-oriented-programming]: https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/oothinking.html -[object]: ../../../../reference/concepts/objects.md +[object]: https://github.com/exercism/v3/blob/main/reference/concepts/objects.md [snake-case]: https://en.wikipedia.org/wiki/Snake_case diff --git a/exercises/concept/lasagna/.docs/introduction.md b/exercises/concept/lasagna/.docs/introduction.md index 4808c0c153..537bc457d9 100644 --- a/exercises/concept/lasagna/.docs/introduction.md +++ b/exercises/concept/lasagna/.docs/introduction.md @@ -51,5 +51,5 @@ calc.multiply(num1: 2, num_2: 5) ``` [object-oriented-programming]: https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/oothinking.html -[object]: ../../../../../../reference/concepts/objects.md +[object]: https://github.com/exercism/v3/blob/main/reference/concepts/objects.md [snake-case]: https://en.wikipedia.org/wiki/Snake_case diff --git a/reference/implementing-a-concept-exercise.md b/reference/implementing-a-concept-exercise.md index a481cd627e..8cb6712479 100644 --- a/reference/implementing-a-concept-exercise.md +++ b/reference/implementing-a-concept-exercise.md @@ -80,11 +80,11 @@ If you have any questions regarding implementing the exercise, please post them [analyzer]: https://github.com/exercism/ruby-analyzer [representer]: https://github.com/exercism/ruby-representer [concept-exercises]: ../exercises/concept/README.md -[how-to-implement-a-concept-exercise]: ../../../docs/maintainers/generic-how-to-implement-a-concept-exercise.md -[docs-concept-exercises]: ../../../docs/concept-exercises.md -[docs-rationale-for-v3]: ../../../docs/rationale-for-v3.md -[docs-features-of-v3]: ../../../docs/features-of-v3.md +[how-to-implement-a-concept-exercise]: https://github.com/exercism/v3/blob/main/docs/maintainers/generic-how-to-implement-a-concept-exercise.md +[docs-concept-exercises]: https://github.com/exercism/v3/blob/main/docs/concept-exercises.md +[docs-rationale-for-v3]: https://github.com/exercism/v3/blob/main/docs/rationale-for-v3.md +[docs-features-of-v3]: https://github.com/exercism/v3/blob/main/docs/features-of-v3.md [anatomy-of-a-concept-exercise]: https://www.youtube.com/watch?v=gkbBqd7hPrA [concept-exercise-strings]: ../exercises/concept/strings -[reference]: ../../../reference +[reference]: https://github.com/exercism/v3/blob/main/reference [implemented-exercises]: ../exercises/concept/README.md#implemented-exercises From d08345c5ea1c9705f82cb6424ac1c2e069a7659e Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 29 Jan 2021 16:35:19 +0100 Subject: [PATCH 102/102] [v3] Fix configlet CI workflow --- .github/workflows/configlet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/configlet.yml b/.github/workflows/configlet.yml index d25e20f506..9e6ce9f778 100644 --- a/.github/workflows/configlet.yml +++ b/.github/workflows/configlet.yml @@ -19,4 +19,4 @@ jobs: uses: exercism/github-actions/configlet-ci@main - name: Configlet Linter - run: configlet lint . + run: configlet lint