From 88970632fabe0eb8c116936816dc473f4c40dfa7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 21:18:21 +0200 Subject: [PATCH 001/101] build(deps): bump actions/checkout from 4.1.5 to 4.1.6 (#877) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.5 to 4.1.6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/44c2b7a8a4ea60a981eaca3cf939b5f4305c123b...a5ac7e51b41094c92402da3b24376905380afc29) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/hello-world.yml | 2 +- .github/workflows/verify-code-formatting.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac7ce1bf..7863ef39 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: matrix: compiler: [clang++-6.0, g++-10] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - name: Install Dependencies # Boost must be installed only because the CMake version (3.12) can't # detect the installed Boost version (1.69) @@ -37,7 +37,7 @@ jobs: matrix: compiler: [clang++, g++] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - name: Install Dependencies # Boost must be installed only because the CMake version (3.12) can't # detect the installed Boost version (1.69) @@ -64,7 +64,7 @@ jobs: needs: [linux-min] runs-on: windows-2022 steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - name: Run Tests shell: powershell # Delete the exercises that require Boost to avoid issues with Windows setup. @@ -80,7 +80,7 @@ jobs: needs: [linux-min] runs-on: macOS-latest steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - name: Install Boost run: brew install boost - name: Run Tests diff --git a/.github/workflows/hello-world.yml b/.github/workflows/hello-world.yml index 02f15208..00497494 100644 --- a/.github/workflows/hello-world.yml +++ b/.github/workflows/hello-world.yml @@ -21,7 +21,7 @@ jobs: name: Hello World Fails runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - name: Check Hello World Fails run: bin/check-hello-world.sh env: diff --git a/.github/workflows/verify-code-formatting.yml b/.github/workflows/verify-code-formatting.yml index f336277e..feb5b794 100644 --- a/.github/workflows/verify-code-formatting.yml +++ b/.github/workflows/verify-code-formatting.yml @@ -21,7 +21,7 @@ jobs: runs-on: [ubuntu-22.04] steps: - name: "Checkout code" - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - name: "Verify formatting of all files" if: github.ref == 'refs/heads/master' From 8ccc4730adea6fa1c29db8bbd45a6bd845b595c3 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 16 May 2024 21:18:40 +0200 Subject: [PATCH 002/101] Sync the `pig-latin` exercise's docs with the latest data. (#871) --- .../practice/pig-latin/.docs/instructions.md | 18 ++++-------------- .../practice/pig-latin/.docs/introduction.md | 8 ++++++++ 2 files changed, 12 insertions(+), 14 deletions(-) create mode 100644 exercises/practice/pig-latin/.docs/introduction.md diff --git a/exercises/practice/pig-latin/.docs/instructions.md b/exercises/practice/pig-latin/.docs/instructions.md index 032905aa..57170881 100644 --- a/exercises/practice/pig-latin/.docs/instructions.md +++ b/exercises/practice/pig-latin/.docs/instructions.md @@ -1,20 +1,10 @@ # Instructions -Implement a program that translates from English to Pig Latin. +Your task is to translate text from English to Pig Latin using the following rules: -Pig Latin is a made-up children's language that's intended to be confusing. -It obeys a few simple rules (below), but when it's spoken quickly it's really difficult for non-children (and non-native speakers) to understand. - -- **Rule 1**: If a word begins with a vowel sound, add an "ay" sound to the end of the word. +- **Rule 1**: If a word begins with a vowel sound, add an "ay" sound to the end of the word (e.g. "apple" -> "appleay"). Please note that "xr" and "yt" at the beginning of a word make vowel sounds (e.g. "xray" -> "xrayay", "yttria" -> "yttriaay"). -- **Rule 2**: If a word begins with a consonant sound, move it to the end of the word and then add an "ay" sound to the end of the word. +- **Rule 2**: If a word begins with a consonant sound, move it to the end of the word and then add an "ay" sound to the end of the word (e.g. "pig" -> "igpay"). Consonant sounds can be made up of multiple consonants, such as the "ch" in "chair" or "st" in "stand" (e.g. "chair" -> "airchay"). -- **Rule 3**: If a word starts with a consonant sound followed by "qu", move it to the end of the word, and then add an "ay" sound to the end of the word (e.g. "square" -> "aresquay"). +- **Rule 3**: If a word starts with a consonant sound followed by "qu", move them to the end of the word, and then add an "ay" sound to the end of the word (e.g. "square" -> "aresquay"). - **Rule 4**: If a word contains a "y" after a consonant cluster or as the second letter in a two letter word it makes a vowel sound (e.g. "rhythm" -> "ythmrhay", "my" -> "ymay"). - -There are a few more rules for edge cases, and there are regional variants too. -Check the tests for all the details. - -Read more about [Pig Latin on Wikipedia][pig-latin]. - -[pig-latin]: https://en.wikipedia.org/wiki/Pig_latin diff --git a/exercises/practice/pig-latin/.docs/introduction.md b/exercises/practice/pig-latin/.docs/introduction.md new file mode 100644 index 00000000..04baa475 --- /dev/null +++ b/exercises/practice/pig-latin/.docs/introduction.md @@ -0,0 +1,8 @@ +# Introduction + +Your parents have challenged you and your sibling to a game of two-on-two basketball. +Confident they'll win, they let you score the first couple of points, but then start taking over the game. +Needing a little boost, you start speaking in [Pig Latin][pig-latin], which is a made-up children's language that's difficult for non-children to understand. +This will give you the edge to prevail over your parents! + +[pig-latin]: https://en.wikipedia.org/wiki/Pig_latin From d5215b85d76265ffdce6598e91b12b49fd8b4902 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 16 May 2024 21:18:59 +0200 Subject: [PATCH 003/101] Sync the `spiral-matrix` exercise's docs with the latest data. (#872) --- .../practice/spiral-matrix/.docs/instructions.md | 2 +- .../practice/spiral-matrix/.docs/introduction.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 exercises/practice/spiral-matrix/.docs/introduction.md diff --git a/exercises/practice/spiral-matrix/.docs/instructions.md b/exercises/practice/spiral-matrix/.docs/instructions.md index ba99e12c..01e8a77f 100644 --- a/exercises/practice/spiral-matrix/.docs/instructions.md +++ b/exercises/practice/spiral-matrix/.docs/instructions.md @@ -1,6 +1,6 @@ # Instructions -Given the size, return a square matrix of numbers in spiral order. +Your task is to return a square matrix of a given size. The matrix should be filled with natural numbers, starting from 1 in the top-left corner, increasing in an inward, clockwise spiral order, like these examples: diff --git a/exercises/practice/spiral-matrix/.docs/introduction.md b/exercises/practice/spiral-matrix/.docs/introduction.md new file mode 100644 index 00000000..25c7eb59 --- /dev/null +++ b/exercises/practice/spiral-matrix/.docs/introduction.md @@ -0,0 +1,11 @@ +# Introduction + +In a small village near an ancient forest, there was a legend of a hidden treasure buried deep within the woods. +Despite numerous attempts, no one had ever succeeded in finding it. +This was about to change, however, thanks to a young explorer named Elara. +She had discovered an old document containing instructions on how to locate the treasure. +Using these instructions, Elara was able to draw a map that revealed the path to the treasure. + +To her surprise, the path followed a peculiar clockwise spiral. +It was no wonder no one had been able to find the treasure before! +With the map in hand, Elara embarks on her journey to uncover the hidden treasure. From 59fe86d7294963184eada5e6270f01a68fc7316f Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 16 May 2024 21:19:16 +0200 Subject: [PATCH 004/101] Sync the `anagram` exercise's docs with the latest data. (#873) --- exercises/practice/anagram/.docs/instructions.md | 6 +++--- exercises/practice/anagram/.docs/introduction.md | 12 ++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 exercises/practice/anagram/.docs/introduction.md diff --git a/exercises/practice/anagram/.docs/instructions.md b/exercises/practice/anagram/.docs/instructions.md index 7d1c8283..a7298485 100644 --- a/exercises/practice/anagram/.docs/instructions.md +++ b/exercises/practice/anagram/.docs/instructions.md @@ -1,9 +1,9 @@ # Instructions -An anagram is a rearrangement of letters to form a new word: for example `"owns"` is an anagram of `"snow"`. -A word is not its own anagram: for example, `"stop"` is not an anagram of `"stop"`. +Your task is to, given a target word and a set of candidate words, to find the subset of the candidates that are anagrams of the target. -Given a target word and a set of candidate words, this exercise requests the anagram set: the subset of the candidates that are anagrams of the target. +An anagram is a rearrangement of letters to form a new word: for example `"owns"` is an anagram of `"snow"`. +A word is _not_ its own anagram: for example, `"stop"` is not an anagram of `"stop"`. The target and candidates are words of one or more ASCII alphabetic characters (`A`-`Z` and `a`-`z`). Lowercase and uppercase characters are equivalent: for example, `"PoTS"` is an anagram of `"sTOp"`, but `StoP` is not an anagram of `sTOp`. diff --git a/exercises/practice/anagram/.docs/introduction.md b/exercises/practice/anagram/.docs/introduction.md new file mode 100644 index 00000000..1acbdf00 --- /dev/null +++ b/exercises/practice/anagram/.docs/introduction.md @@ -0,0 +1,12 @@ +# Introduction + +At a garage sale, you find a lovely vintage typewriter at a bargain price! +Excitedly, you rush home, insert a sheet of paper, and start typing away. +However, your excitement wanes when you examine the output: all words are garbled! +For example, it prints "stop" instead of "post" and "least" instead of "stale." +Carefully, you try again, but now it prints "spot" and "slate." +After some experimentation, you find there is a random delay before each letter is printed, which messes up the order. +You now understand why they sold it for so little money! + +You realize this quirk allows you to generate anagrams, which are words formed by rearranging the letters of another word. +Pleased with your finding, you spend the rest of the day generating hundreds of anagrams. From 8f1bf19567c6b43fd67c7db16e90a83b3d23351e Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 16 May 2024 21:19:32 +0200 Subject: [PATCH 005/101] Sync the `knapsack` exercise's docs with the latest data. (#874) --- .../practice/knapsack/.docs/instructions.md | 20 +++++-------------- .../practice/knapsack/.docs/introduction.md | 8 ++++++++ 2 files changed, 13 insertions(+), 15 deletions(-) create mode 100644 exercises/practice/knapsack/.docs/introduction.md diff --git a/exercises/practice/knapsack/.docs/instructions.md b/exercises/practice/knapsack/.docs/instructions.md index fadcee1b..3411db98 100644 --- a/exercises/practice/knapsack/.docs/instructions.md +++ b/exercises/practice/knapsack/.docs/instructions.md @@ -1,24 +1,15 @@ # Instructions -In this exercise, let's try to solve a classic problem. +Your task is to determine which items to take so that the total value of his selection is maximized, taking into account the knapsack's carrying capacity. -Bob is a thief. -After months of careful planning, he finally manages to crack the security systems of a high-class apartment. - -In front of him are many items, each with a value (v) and weight (w). -Bob, of course, wants to maximize the total value he can get; he would gladly take all of the items if he could. -However, to his horror, he realizes that the knapsack he carries with him can only hold so much weight (W). - -Given a knapsack with a specific carrying capacity (W), help Bob determine the maximum value he can get from the items in the house. -Note that Bob can take only one of each item. - -All values given will be strictly positive. Items will be represented as a list of items. Each item will have a weight and value. +All values given will be strictly positive. +Bob can take only one of each item. For example: -```none +```text Items: [ { "weight": 5, "value": 10 }, { "weight": 4, "value": 40 }, @@ -26,10 +17,9 @@ Items: [ { "weight": 4, "value": 50 } ] -Knapsack Limit: 10 +Knapsack Maximum Weight: 10 ``` For the above, the first item has weight 5 and value 10, the second item has weight 4 and value 40, and so on. - In this example, Bob should take the second and fourth item to maximize his value, which, in this case, is 90. He cannot get more than 90 as his knapsack has a weight limit of 10. diff --git a/exercises/practice/knapsack/.docs/introduction.md b/exercises/practice/knapsack/.docs/introduction.md new file mode 100644 index 00000000..9b2bed8b --- /dev/null +++ b/exercises/practice/knapsack/.docs/introduction.md @@ -0,0 +1,8 @@ +# Introduction + +Bob is a thief. +After months of careful planning, he finally manages to crack the security systems of a fancy store. + +In front of him are many items, each with a value and weight. +Bob would gladly take all of the items, but his knapsack can only hold so much weight. +Bob has to carefully consider which items to take so that the total value of his selection is maximized. From 5f2e503fc89262f1e186f53679a757013bb5c8a7 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 16 May 2024 21:19:50 +0200 Subject: [PATCH 006/101] Sync the `kindergarten-garden` exercise's docs with the latest data. (#875) --- .../kindergarten-garden/.docs/instructions.md | 32 +++++++++---------- .../kindergarten-garden/.docs/introduction.md | 6 ++++ 2 files changed, 21 insertions(+), 17 deletions(-) create mode 100644 exercises/practice/kindergarten-garden/.docs/introduction.md diff --git a/exercises/practice/kindergarten-garden/.docs/instructions.md b/exercises/practice/kindergarten-garden/.docs/instructions.md index 472ee26f..6fe11a58 100644 --- a/exercises/practice/kindergarten-garden/.docs/instructions.md +++ b/exercises/practice/kindergarten-garden/.docs/instructions.md @@ -1,16 +1,21 @@ # Instructions -Given a diagram, determine which plants each child in the kindergarten class is -responsible for. +Your task is to, given a diagram, determine which plants each child in the kindergarten class is responsible for. -The kindergarten class is learning about growing plants. -The teacher thought it would be a good idea to give them actual seeds, plant them in actual dirt, and grow actual plants. +There are 12 children in the class: + +- Alice, Bob, Charlie, David, Eve, Fred, Ginny, Harriet, Ileana, Joseph, Kincaid, and Larry. + +Four different types of seeds are planted: -They've chosen to grow grass, clover, radishes, and violets. +| Plant | Diagram encoding | +| ------ | ---------------- | +| Grass | G | +| Clover | C | +| Radish | R | +| Violet | V | -To this end, the children have put little cups along the window sills, and -planted one type of plant in each cup, choosing randomly from the available -types of seeds. +Each child gets four cups, two on each row: ```text [window][window][window] @@ -18,16 +23,9 @@ types of seeds. ........................ ``` -There are 12 children in the class: - -- Alice, Bob, Charlie, David, -- Eve, Fred, Ginny, Harriet, -- Ileana, Joseph, Kincaid, and Larry. - -Each child gets 4 cups, two on each row. -Their teacher assigns cups to the children alphabetically by their names. +Their teacher assigns cups to the children alphabetically by their names, which means that Alice comes first and Larry comes last. -The following diagram represents Alice's plants: +Here is an example diagram representing Alice's plants: ```text [window][window][window] diff --git a/exercises/practice/kindergarten-garden/.docs/introduction.md b/exercises/practice/kindergarten-garden/.docs/introduction.md new file mode 100644 index 00000000..5ad97d23 --- /dev/null +++ b/exercises/practice/kindergarten-garden/.docs/introduction.md @@ -0,0 +1,6 @@ +# Introduction + +The kindergarten class is learning about growing plants. +The teacher thought it would be a good idea to give the class seeds to plant and grow in the dirt. +To this end, the children have put little cups along the window sills and planted one type of plant in each cup. +The children got to pick their favorites from four available types of seeds: grass, clover, radishes, and violets. From 5270a9e1294b624bc189ca77899f014fa1a471ec Mon Sep 17 00:00:00 2001 From: WesMorganCold <161843099+WesMorganCold@users.noreply.github.com> Date: Thu, 16 May 2024 15:22:18 -0400 Subject: [PATCH 007/101] tests: minor typo fix (#876) Corrected the word 'guest' in 2 places that should have been 'user' and 'mod' [no important files changed] --- .../concept/troll-the-trolls/troll_the_trolls_test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/exercises/concept/troll-the-trolls/troll_the_trolls_test.cpp b/exercises/concept/troll-the-trolls/troll_the_trolls_test.cpp index 3a6ec2c4..2d775c35 100644 --- a/exercises/concept/troll-the-trolls/troll_the_trolls_test.cpp +++ b/exercises/concept/troll-the-trolls/troll_the_trolls_test.cpp @@ -297,7 +297,7 @@ TEST_CASE("Guests have second lowest priority", "[task_5]") { } TEST_CASE("Users have second highest priority", "[task_5]") { - // First player is a guest + // First player is a user AccountStatus player1{AccountStatus::user}; AccountStatus player2{AccountStatus::guest}; @@ -312,7 +312,7 @@ TEST_CASE("Users have second highest priority", "[task_5]") { player2 = AccountStatus::mod; REQUIRE_FALSE(has_priority(player1, player2)); - // Second player is a guest + // Second player is a user player2 = AccountStatus::user; player1 = AccountStatus::troll; @@ -326,7 +326,7 @@ TEST_CASE("Users have second highest priority", "[task_5]") { } TEST_CASE("Moderators have highest priority", "[task_5]") { - // First player is a guest + // First player is a mod AccountStatus player1{AccountStatus::mod}; AccountStatus player2{AccountStatus::guest}; @@ -341,7 +341,7 @@ TEST_CASE("Moderators have highest priority", "[task_5]") { player2 = AccountStatus::mod; REQUIRE_FALSE(has_priority(player1, player2)); - // Second player is a guest + // Second player is a mod player2 = AccountStatus::mod; player1 = AccountStatus::troll; From 1fada1a2e134ccd5088717494be465b4ba7a403a Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Mon, 27 May 2024 14:42:31 +0200 Subject: [PATCH 008/101] Sync the `bank-account` exercise's docs with the latest data. (#879) --- .../bank-account/.docs/instructions.md | 12 +++++------ .../bank-account/.docs/introduction.md | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 exercises/practice/bank-account/.docs/introduction.md diff --git a/exercises/practice/bank-account/.docs/instructions.md b/exercises/practice/bank-account/.docs/instructions.md index f536fdbb..0955520b 100644 --- a/exercises/practice/bank-account/.docs/instructions.md +++ b/exercises/practice/bank-account/.docs/instructions.md @@ -1,12 +1,10 @@ # Instructions -Simulate a bank account supporting opening/closing, withdrawals, and deposits of money. -Watch out for concurrent transactions! +Your task is to implement bank accounts supporting opening/closing, withdrawals, and deposits of money. -A bank account can be accessed in multiple ways. -Clients can make deposits and withdrawals using the internet, mobile phones, etc. -Shops can charge against the account. - -Create an account that can be accessed from multiple threads/processes (terminology depends on your programming language). +As bank accounts can be accessed in many different ways (internet, mobile phones, automatic charges), your bank software must allow accounts to be safely accessed from multiple threads/processes (terminology depends on your programming language) in parallel. +For example, there may be many deposits and withdrawals occurring in parallel; you need to ensure there is no [race conditions][wikipedia] between when you read the account balance and set the new balance. It should be possible to close an account; operations against a closed account must fail. + +[wikipedia]: https://en.wikipedia.org/wiki/Race_condition#In_software diff --git a/exercises/practice/bank-account/.docs/introduction.md b/exercises/practice/bank-account/.docs/introduction.md new file mode 100644 index 00000000..650b5d9c --- /dev/null +++ b/exercises/practice/bank-account/.docs/introduction.md @@ -0,0 +1,20 @@ +# Introduction + +After years of filling out forms and waiting, you've finally acquired your banking license. +This means you are now officially eligible to open your own bank, hurray! + +Your first priority is to get the IT systems up and running. +After a day of hard work, you can already open and close accounts, as well as handle withdrawals and deposits. + +Since you couldn't be bothered writing tests, you invite some friends to help test the system. +However, after just five minutes, one of your friends claims they've lost money! +While you're confident your code is bug-free, you start looking through the logs to investigate. + +Ah yes, just as you suspected, your friend is at fault! +They shared their test credentials with another friend, and together they conspired to make deposits and withdrawals from the same account _in parallel_. +Who would do such a thing? + +While you argue that it's physically _impossible_ for someone to access their account in parallel, your friend smugly notifies you that the banking rules _require_ you to support this. +Thus, no parallel banking support, no go-live signal. +Sighing, you create a mental note to work on this tomorrow. +This will set your launch date back at _least_ one more day, but well... From d51a99eafe63f3d5233a6b648999575c8e07321d Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Tue, 28 May 2024 16:27:57 +0200 Subject: [PATCH 009/101] Sync the `pig-latin` exercise's docs with the latest data. (#880) --- .../practice/pig-latin/.docs/instructions.md | 52 ++++++++++++++++--- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/exercises/practice/pig-latin/.docs/instructions.md b/exercises/practice/pig-latin/.docs/instructions.md index 57170881..6c843080 100644 --- a/exercises/practice/pig-latin/.docs/instructions.md +++ b/exercises/practice/pig-latin/.docs/instructions.md @@ -1,10 +1,46 @@ # Instructions -Your task is to translate text from English to Pig Latin using the following rules: - -- **Rule 1**: If a word begins with a vowel sound, add an "ay" sound to the end of the word (e.g. "apple" -> "appleay"). - Please note that "xr" and "yt" at the beginning of a word make vowel sounds (e.g. "xray" -> "xrayay", "yttria" -> "yttriaay"). -- **Rule 2**: If a word begins with a consonant sound, move it to the end of the word and then add an "ay" sound to the end of the word (e.g. "pig" -> "igpay"). - Consonant sounds can be made up of multiple consonants, such as the "ch" in "chair" or "st" in "stand" (e.g. "chair" -> "airchay"). -- **Rule 3**: If a word starts with a consonant sound followed by "qu", move them to the end of the word, and then add an "ay" sound to the end of the word (e.g. "square" -> "aresquay"). -- **Rule 4**: If a word contains a "y" after a consonant cluster or as the second letter in a two letter word it makes a vowel sound (e.g. "rhythm" -> "ythmrhay", "my" -> "ymay"). +Your task is to translate text from English to Pig Latin. +The translation is defined using four rules, which look at the pattern of vowels and consonants at the beginning of a word. +These rules look at each word's use of vowels and consonants: + +- vowels: the letters `a`, `e`, `i`, `o`, and `u` +- consonants: the other 21 letters of the English alphabet + +## Rule 1 + +If a word begins with a vowel, or starts with `"xr"` or `"yt"`, add an `"ay"` sound to the end of the word. + +For example: + +- `"apple"` -> `"appleay"` (starts with vowel) +- `"xray"` -> `"xrayay"` (starts with `"xr"`) +- `"yttria"` -> `"yttriaay"` (starts with `"yt"`) + +## Rule 2 + +If a word begins with a one or more consonants, first move those consonants to the end of the word and then add an `"ay"` sound to the end of the word. + +For example: + +- `"pig"` -> `"igp"` -> `"igpay"` (starts with single consonant) +- `"chair"` -> `"airch"` -> `"airchay"` (starts with multiple consonants) +- `"thrush"` -> `"ushthr"` -> `"ushthray"` (starts with multiple consonants) + +## Rule 3 + +If a word starts with zero or more consonants followed by `"qu"`, first move those consonants (if any) and the `"qu"` part to the end of the word, and then add an `"ay"` sound to the end of the word. + +For example: + +- `"quick"` -> `"ickqu"` -> `"ay"` (starts with `"qu"`, no preceding consonants) +- `"square"` -> `"aresqu"` -> `"aresquay"` (starts with one consonant followed by `"qu`") + +## Rule 4 + +If a word starts with one or more consonants followed by `"y"`, first move the consonants preceding the `"y"`to the end of the word, and then add an `"ay"` sound to the end of the word. + +Some examples: + +- `"my"` -> `"ym"` -> `"ymay"` (starts with single consonant followed by `"y"`) +- `"rhythm"` -> `"ythmrh"` -> `"ythmrhay"` (starts with multiple consonants followed by `"y"`) From 69e52dd980bf551c7e7b8f35084bb718e2a91cad Mon Sep 17 00:00:00 2001 From: tanno <94481731+tanno1@users.noreply.github.com> Date: Tue, 28 May 2024 12:04:24 -0700 Subject: [PATCH 010/101] test(phone numbers): update test cases to match problem spec (#870) --- .../practice/phone-number/.meta/tests.toml | 33 ++++- .../phone-number/phone_number_test.cpp | 120 ++++++++++-------- 2 files changed, 98 insertions(+), 55 deletions(-) diff --git a/exercises/practice/phone-number/.meta/tests.toml b/exercises/practice/phone-number/.meta/tests.toml index 6365e12c..24dbf07a 100644 --- a/exercises/practice/phone-number/.meta/tests.toml +++ b/exercises/practice/phone-number/.meta/tests.toml @@ -1,6 +1,13 @@ -# This is an auto-generated file. Regular comments will be removed when this -# file is regenerated. Regenerating will not touch any manually added keys, -# so comments can be added in a "comment" key. +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. [79666dce-e0f1-46de-95a1-563802913c35] description = "cleans the number" @@ -13,6 +20,11 @@ description = "cleans numbers with multiple spaces" [598d8432-0659-4019-a78b-1c6a73691d21] description = "invalid when 9 digits" +include = false + +[2de74156-f646-42b5-8638-0ef1d8b58bc2] +description = "invalid when 9 digits" +reimplements = "598d8432-0659-4019-a78b-1c6a73691d21" [57061c72-07b5-431f-9766-d97da7c4399d] description = "invalid when 11 digits does not start with a 1" @@ -25,12 +37,27 @@ description = "valid when 11 digits and starting with 1 even with punctuation" [c6a5f007-895a-4fc5-90bc-a7e70f9b5cad] description = "invalid when more than 11 digits" +include = false + +[4a1509b7-8953-4eec-981b-c483358ff531] +description = "invalid when more than 11 digits" +reimplements = "c6a5f007-895a-4fc5-90bc-a7e70f9b5cad" [63f38f37-53f6-4a5f-bd86-e9b404f10a60] description = "invalid with letters" +include = false + +[eb8a1fc0-64e5-46d3-b0c6-33184208e28a] +description = "invalid with letters" +reimplements = "63f38f37-53f6-4a5f-bd86-e9b404f10a60" [4bd97d90-52fd-45d3-b0db-06ab95b1244e] description = "invalid with punctuations" +include = false + +[065f6363-8394-4759-b080-e6c8c351dd1f] +description = "invalid with punctuations" +reimplements = "4bd97d90-52fd-45d3-b0db-06ab95b1244e" [d77d07f8-873c-4b17-8978-5f66139bf7d7] description = "invalid if area code starts with 0" diff --git a/exercises/practice/phone-number/phone_number_test.cpp b/exercises/practice/phone-number/phone_number_test.cpp index 04d04209..2757bb22 100644 --- a/exercises/practice/phone-number/phone_number_test.cpp +++ b/exercises/practice/phone-number/phone_number_test.cpp @@ -1,98 +1,114 @@ #include "phone_number.h" - #ifdef EXERCISM_TEST_SUITE #include #else #include "test/catch.hpp" #endif -#include -TEST_CASE("cleans_the_number") { - REQUIRE("2234567890" == phone_number::phone_number("(223) 456-7890").number()); +TEST_CASE("cleans_the_number", "[79666dce-e0f1-46de-95a1-563802913c35]") { + REQUIRE("2234567890" == + phone_number::phone_number("(223) 456-7890").number()); } #if defined(EXERCISM_RUN_ALL_TESTS) -TEST_CASE("cleans_numbers_with_dots") { - REQUIRE("2234567890" == phone_number::phone_number("223.456.7890").number()); -} - -TEST_CASE("cleans_numbers_with_spaces") { - REQUIRE("2234567890" == phone_number::phone_number("223 456 7890 ").number()); -} - -TEST_CASE("has_an_area_code") { - REQUIRE("223" == phone_number::phone_number("+1 (223) 456-7890").area_code()); +TEST_CASE("cleans_numbers_with_dots", + "[c360451f-549f-43e4-8aba-fdf6cb0bf83f]") { + REQUIRE("2234567890" == + phone_number::phone_number("223.456.7890").number()); } -TEST_CASE("formats_a_number") { - const phone_number::phone_number phone("+1 (223) 456-7890"); - REQUIRE("(223) 456-7890" == std::string(phone)); +TEST_CASE("cleans_numbers_with_multiple_spaces", + "[08f94c34-9a37-46a2-a123-2a8e9727395d]") { + REQUIRE("2234567890" == + phone_number::phone_number("223 456 7890 ").number()); } -TEST_CASE("invalid_when_9_digits") { - REQUIRE_THROWS_AS(phone_number::phone_number("123456789"), std::domain_error); +TEST_CASE("invalid_when_9_digits", "[2de74156-f646-42b5-8638-0ef1d8b58bc2]") { + REQUIRE_THROWS_AS(phone_number::phone_number("123456789"), + std::domain_error); } -TEST_CASE("invalid_when_11_digits_does_not_start_with_a_1") { - REQUIRE_THROWS_AS(phone_number::phone_number("22234567890"), std::domain_error); +TEST_CASE("invalid_when_11_digits_does_not_start_with_a_1", + "[57061c72-07b5-431f-9766-d97da7c4399d]") { + REQUIRE_THROWS_AS(phone_number::phone_number("22234567890"), + std::domain_error); } -TEST_CASE("valid_when_11_digits_and_starting_with_1") { - REQUIRE("2234567890" == phone_number::phone_number("12234567890").number()); +TEST_CASE("valid_when_11_digits_and_starting_with_1", + "[9962cbf3-97bb-4118-ba9b-38ff49c64430]") { + REQUIRE("2234567890" == phone_number::phone_number("12234567890").number()); } -TEST_CASE( - "valid_when_11_digits_and_starting_with_1_even_with_punctuation") { - REQUIRE("2234567890" == phone_number::phone_number("+1 (223) 456-7890").number()); +TEST_CASE("valid_when_11_digits_and_starting_with_1_even_with_punctuation", + "[fa724fbf-054c-4d91-95da-f65ab5b6dbca]") { + REQUIRE("2234567890" == + phone_number::phone_number("+1 (223) 456-7890").number()); } -TEST_CASE("invalid_when_more_than_11_digits") { - REQUIRE_THROWS_AS(phone_number::phone_number("321234567890"), std::domain_error); +TEST_CASE("invalid_when_more_than_11_digits", + "[4a1509b7-8953-4eec-981b-c483358ff531]") { + REQUIRE_THROWS_AS(phone_number::phone_number("321234567890"), + std::domain_error); } -TEST_CASE("invalid_with_letters") { - REQUIRE_THROWS_AS(phone_number::phone_number("123-abc-7890"), std::domain_error); +TEST_CASE("invalid_with_letters", "[eb8a1fc0-64e5-46d3-b0c6-33184208e28a]") { + REQUIRE_THROWS_AS(phone_number::phone_number("123-abc-7890"), + std::domain_error); } -TEST_CASE("invalid_with_punctuation") { - REQUIRE_THROWS_AS(phone_number::phone_number("123-@:!-7890"), std::domain_error); +TEST_CASE("invalid_with_punctuation", + "[065f6363-8394-4759-b080-e6c8c351dd1f]") { + REQUIRE_THROWS_AS(phone_number::phone_number("123-@:!-7890"), + std::domain_error); } -TEST_CASE("invalid_if_area_code_starts_with_0") { - REQUIRE_THROWS_AS(phone_number::phone_number("(023) 456-7890"), std::domain_error); +TEST_CASE("invalid_if_area_code_starts_with_0", + "[d77d07f8-873c-4b17-8978-5f66139bf7d7]") { + REQUIRE_THROWS_AS(phone_number::phone_number("(023) 456-7890"), + std::domain_error); } -TEST_CASE("invalid_if_area_code_starts_with_1") { - REQUIRE_THROWS_AS(phone_number::phone_number("(123) 456-7890"), std::domain_error); +TEST_CASE("invalid_if_area_code_starts_with_1", + "[c7485cfb-1e7b-4081-8e96-8cdb3b77f15e]") { + REQUIRE_THROWS_AS(phone_number::phone_number("(123) 456-7890"), + std::domain_error); } -TEST_CASE("invalid_if_exchange_code_starts_with_0") { - REQUIRE_THROWS_AS(phone_number::phone_number("(223) 056-7890"), std::domain_error); +TEST_CASE("invalid_if_exchange_code_starts_with_0", + "[4d622293-6976-413d-b8bf-dd8a94d4e2ac]") { + REQUIRE_THROWS_AS(phone_number::phone_number("(223) 056-7890"), + std::domain_error); } -TEST_CASE("invalid_if_exchange_code_starts_with_1") { - REQUIRE_THROWS_AS(phone_number::phone_number("(223) 156-7890"), std::domain_error); +TEST_CASE("invalid_if_exchange_code_starts_with_1", + "[4cef57b4-7d8e-43aa-8328-1e1b89001262]") { + REQUIRE_THROWS_AS(phone_number::phone_number("(223) 156-7890"), + std::domain_error); } -TEST_CASE( - "invalid_if_area_code_starts_with_0_on_valid_11_digit_number") { - REQUIRE_THROWS_AS(phone_number::phone_number("1 (023) 456-7890"), std::domain_error); +TEST_CASE("invalid_if_area_code_starts_with_0_on_valid_11_digit_number", + "[9925b09c-1a0d-4960-a197-5d163cbe308c]") { + REQUIRE_THROWS_AS(phone_number::phone_number("1 (023) 456-7890"), + std::domain_error); } -TEST_CASE( - "invalid_if_area_code_starts_with_1_on_valid_11_digit_number") { - REQUIRE_THROWS_AS(phone_number::phone_number("1 (123) 456-7890"), std::domain_error); +TEST_CASE("invalid_if_area_code_starts_with_1_on_valid_11_digit_number", + "[3f809d37-40f3-44b5-ad90-535838b1a816]") { + REQUIRE_THROWS_AS(phone_number::phone_number("1 (123) 456-7890"), + std::domain_error); } -TEST_CASE( - "invalid_if_exchange_code_starts_with_0_on_valid_11_digit_number") { - REQUIRE_THROWS_AS(phone_number::phone_number("1 (223) 056-7890"), std::domain_error); +TEST_CASE("invalid_if_exchange_code_starts_with_0_on_valid_11_digit_number", + "[e08e5532-d621-40d4-b0cc-96c159276b65]") { + REQUIRE_THROWS_AS(phone_number::phone_number("1 (223) 056-7890"), + std::domain_error); } -TEST_CASE( - "invalid_if_exchange_code_starts_with_1_on_valid_11_digit_number") { - REQUIRE_THROWS_AS(phone_number::phone_number("1 (223) 156-7890"), std::domain_error); +TEST_CASE("invalid_if_exchange_code_starts_with_1_on_valid_11_digit_number", + "[57b32f3d-696a-455c-8bf1-137b6d171cdf]") { + REQUIRE_THROWS_AS(phone_number::phone_number("1 (223) 156-7890"), + std::domain_error); } #endif \ No newline at end of file From b23bddf7ccf7375ff27ae7d3a9dcac849ecdf285 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 6 Jun 2024 09:39:02 +0200 Subject: [PATCH 011/101] Sync the `meetup` exercise's docs with the latest data. (#882) --- .../practice/meetup/.docs/instructions.md | 35 +++++-------------- .../practice/meetup/.docs/introduction.md | 29 +++++++++++++++ 2 files changed, 38 insertions(+), 26 deletions(-) create mode 100644 exercises/practice/meetup/.docs/introduction.md diff --git a/exercises/practice/meetup/.docs/instructions.md b/exercises/practice/meetup/.docs/instructions.md index 0694ef58..000de2fd 100644 --- a/exercises/practice/meetup/.docs/instructions.md +++ b/exercises/practice/meetup/.docs/instructions.md @@ -1,11 +1,10 @@ # Instructions -Recurring monthly meetups are generally scheduled on the given weekday of a given week each month. -In this exercise you will be given the recurring schedule, along with a month and year, and then asked to find the exact date of the meetup. +Your task is to find the exact date of a meetup, given a month, year, weekday and week. -For example a meetup might be scheduled on the _first Monday_ of every month. -You might then be asked to find the date that this meetup will happen in January 2018. -In other words, you need to determine the date of the first Monday of January 2018. +There are five week values to consider: `first`, `second`, `third`, `fourth`, `last`, `teenth`. + +For example, you might be asked to find the date for the meetup on the first Monday in January 2018 (January 1, 2018). Similarly, you might be asked to find: @@ -13,29 +12,13 @@ Similarly, you might be asked to find: - the teenth Wednesday of May 2020 (May 13, 2020) - the fourth Sunday of July 2021 (July 25, 2021) - the last Thursday of November 2022 (November 24, 2022) +- the teenth Saturday of August 1953 (August 15, 1953) -The descriptors you are expected to process are: `first`, `second`, `third`, `fourth`, `last`, `teenth`. - -Note that descriptor `teenth` is a made-up word. - -It refers to the seven numbers that end in '-teen' in English: 13, 14, 15, 16, 17, 18, and 19. -But general descriptions of dates use ordinal numbers, e.g. the _first_ Monday, the _third_ Tuesday. - -For the numbers ending in '-teen', that becomes: - -- 13th (thirteenth) -- 14th (fourteenth) -- 15th (fifteenth) -- 16th (sixteenth) -- 17th (seventeenth) -- 18th (eighteenth) -- 19th (nineteenth) +## Teenth -So there are seven numbers ending in '-teen'. -And there are also seven weekdays (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday). -Therefore, it is guaranteed that each day of the week (Monday, Tuesday, ...) will have exactly one numbered day ending with "teen" each month. +The teenth week refers to the seven days in a month that end in '-teenth' (13th, 14th, 15th, 16th, 17th, 18th and 19th). -If asked to find the teenth Saturday of August, 1953 (or, alternately the "Saturteenth" of August, 1953), we need to look at the calendar for August 1953: +If asked to find the teenth Saturday of August, 1953, we check its calendar: ```plaintext August 1953 @@ -48,4 +31,4 @@ Su Mo Tu We Th Fr Sa 30 31 ``` -The Saturday that has a number ending in '-teen' is August 15, 1953. +From this we find that the teenth Saturday is August 15, 1953. diff --git a/exercises/practice/meetup/.docs/introduction.md b/exercises/practice/meetup/.docs/introduction.md new file mode 100644 index 00000000..29170ef1 --- /dev/null +++ b/exercises/practice/meetup/.docs/introduction.md @@ -0,0 +1,29 @@ +# Introduction + +Every month, your partner meets up with their best friend. +Both of them have very busy schedules, making it challenging to find a suitable date! +Given your own busy schedule, your partner always double-checks potential meetup dates with you: + +- "Can I meet up on the first Friday of next month?" +- "What about the third Wednesday?" +- "Maybe the last Sunday?" + +In this month's call, your partner asked you this question: + +- "I'd like to meet up on the teenth Thursday; is that okay?" + +Confused, you ask what a "teenth" day is. +Your partner explains that a teenth day, a concept they made up, refers to the days in a month that end in '-teenth': + +- 13th (thirteenth) +- 14th (fourteenth) +- 15th (fifteenth) +- 16th (sixteenth) +- 17th (seventeenth) +- 18th (eighteenth) +- 19th (nineteenth) + +As there are also seven weekdays, it is guaranteed that each day of the week has _exactly one_ teenth day each month. + +Now that you understand the concept of a teenth day, you check your calendar. +You don't have anything planned on the teenth Thursday, so you happily confirm the date with your partner. From d50951d8979f7e0ad1c94a009b26cf3e17ed1e50 Mon Sep 17 00:00:00 2001 From: Fabio Di Natale Date: Thu, 6 Jun 2024 11:43:09 +0200 Subject: [PATCH 012/101] docs: fix instructions of lasagna master (#852) * Update instructions.md The instructions of Task 3 have been clarified. * Correcting after first revision * Update exercises/concept/lasagna-master/.docs/instructions.md Co-authored-by: Christian Willner <34183939+vaeng@users.noreply.github.com> * Adding the possibility of using a reference also for the second parameter --------- Co-authored-by: Christian Willner <34183939+vaeng@users.noreply.github.com> --- exercises/concept/lasagna-master/.docs/instructions.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/concept/lasagna-master/.docs/instructions.md b/exercises/concept/lasagna-master/.docs/instructions.md index 0d13bd22..9d2e08a2 100644 --- a/exercises/concept/lasagna-master/.docs/instructions.md +++ b/exercises/concept/lasagna-master/.docs/instructions.md @@ -49,12 +49,12 @@ It was amazing and had something special to it. The friend sent you the list of ingredients and told you the last item on the list is the "secret ingredient" that made the meal so special. Now you want to add that secret ingredient to your recipe as well. -Write a function `addSecretIngredient` that accepts two `string` vectors of ingredients as parameters. -The first parameter is the list your friend sent you, the second is the ingredient list of your own recipe. +Write a function `addSecretIngredient` that accepts two `vector of strings` as parameters. +The first parameter is a _reference_ to the ingredients of your own recipe, and the second _vector_ of strings has the ingredients your friend sent you. The last element in your ingredient list is always `"?"`. The function should replace it with the last item from your friends list. **Note:** `addSecretIngredient` does not return anything - you should modify the list of your ingredients directly. -The list with your friend's ingredients should **not** be modified. +The list with your friend's ingredients can also be a reference (for improving the performance), but it should **not** be modified. Make sure the list will not be modified with a `const` reference. ```cpp From e2a1fdf42bb849c72061409c6bf2d1bac608ec4b Mon Sep 17 00:00:00 2001 From: KrishWu <66881117+KrishWu@users.noreply.github.com> Date: Thu, 6 Jun 2024 23:59:18 -0700 Subject: [PATCH 013/101] docs: about.md small typo (#883) Small typo where length was spelled lenghth instead of length. --- concepts/functions/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/functions/about.md b/concepts/functions/about.md index e2f12ed3..89748088 100644 --- a/concepts/functions/about.md +++ b/concepts/functions/about.md @@ -66,7 +66,7 @@ class Stubborn { response = reply; } string answer(const string& question) const { - if (question.lenghth() == 0) { return "";} + if (question.length() == 0) { return "";} return response; } private: From f11297e5c639ebd19957f550d72575d20640346a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 10:17:47 +0200 Subject: [PATCH 014/101] build(deps): bump actions/checkout from 4.1.6 to 4.1.7 (#884) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.6 to 4.1.7. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/a5ac7e51b41094c92402da3b24376905380afc29...692973e3d937129bcbf40652eb9f2f61becf3332) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/hello-world.yml | 2 +- .github/workflows/verify-code-formatting.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7863ef39..73090b7f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: matrix: compiler: [clang++-6.0, g++-10] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - name: Install Dependencies # Boost must be installed only because the CMake version (3.12) can't # detect the installed Boost version (1.69) @@ -37,7 +37,7 @@ jobs: matrix: compiler: [clang++, g++] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - name: Install Dependencies # Boost must be installed only because the CMake version (3.12) can't # detect the installed Boost version (1.69) @@ -64,7 +64,7 @@ jobs: needs: [linux-min] runs-on: windows-2022 steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - name: Run Tests shell: powershell # Delete the exercises that require Boost to avoid issues with Windows setup. @@ -80,7 +80,7 @@ jobs: needs: [linux-min] runs-on: macOS-latest steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - name: Install Boost run: brew install boost - name: Run Tests diff --git a/.github/workflows/hello-world.yml b/.github/workflows/hello-world.yml index 00497494..405a6404 100644 --- a/.github/workflows/hello-world.yml +++ b/.github/workflows/hello-world.yml @@ -21,7 +21,7 @@ jobs: name: Hello World Fails runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - name: Check Hello World Fails run: bin/check-hello-world.sh env: diff --git a/.github/workflows/verify-code-formatting.yml b/.github/workflows/verify-code-formatting.yml index feb5b794..b2284594 100644 --- a/.github/workflows/verify-code-formatting.yml +++ b/.github/workflows/verify-code-formatting.yml @@ -21,7 +21,7 @@ jobs: runs-on: [ubuntu-22.04] steps: - name: "Checkout code" - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - name: "Verify formatting of all files" if: github.ref == 'refs/heads/master' From b6eb4e4075351e74cbe0f1eb69bb9c49a2e00f17 Mon Sep 17 00:00:00 2001 From: chikkkkka Date: Sat, 22 Jun 2024 12:17:18 -0700 Subject: [PATCH 015/101] concepts/switch: fix typo (#887) --- concepts/switch/introduction.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/concepts/switch/introduction.md b/concepts/switch/introduction.md index 8a306245..0ba56114 100644 --- a/concepts/switch/introduction.md +++ b/concepts/switch/introduction.md @@ -58,5 +58,5 @@ case 3: default: book_house(group_size); } -// book_apartment happens wheng roup_size is 2 or 3 -``` \ No newline at end of file +// book_apartment happens wheng group_size is 2 or 3 +``` From 98bd9edb4a8282848cbfca05a5ddfa6ee00b5948 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 22 Jun 2024 21:46:50 +0200 Subject: [PATCH 016/101] concept switch: fix typo (#888) --- concepts/switch/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/switch/introduction.md b/concepts/switch/introduction.md index 0ba56114..2963c831 100644 --- a/concepts/switch/introduction.md +++ b/concepts/switch/introduction.md @@ -58,5 +58,5 @@ case 3: default: book_house(group_size); } -// book_apartment happens wheng group_size is 2 or 3 +// book_apartment happens when group_size is 2 or 3 ``` From 3a3e34ec42f514e6736afb33ec470114a8b63acc Mon Sep 17 00:00:00 2001 From: Ricardo Chiriboga <115743728+rachirib@users.noreply.github.com> Date: Sun, 23 Jun 2024 06:02:44 +1000 Subject: [PATCH 017/101] concept/loops: fix typo (#886) i is the counter for the module of 2, instead of n. --- concepts/loops/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/loops/introduction.md b/concepts/loops/introduction.md index 690d8e88..d6793636 100644 --- a/concepts/loops/introduction.md +++ b/concepts/loops/introduction.md @@ -84,7 +84,7 @@ In contrast, the keyword `continue` only stops the execution of the current iter ```cpp int equal_sum{0}; for (int i{1}; i < 7; ++i) { - if (n%2 == 1) { + if (i%2 == 1) { continue; } equal_sum += i; From 17f434a54c383ba32be0d310e545aa051b494e36 Mon Sep 17 00:00:00 2001 From: Ricardo Chiriboga <115743728+rachirib@users.noreply.github.com> Date: Sun, 23 Jun 2024 20:16:18 +1000 Subject: [PATCH 018/101] interest-is-interesting: fix typo (#889) Fixing this also on the documentation of the exercise, This should be pointing to `i`. Previous PR was fixing it on the learning section but it seems it is also on the exercise itself --- exercises/concept/interest-is-interesting/.docs/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/interest-is-interesting/.docs/introduction.md b/exercises/concept/interest-is-interesting/.docs/introduction.md index 05d1f14b..52cd111e 100644 --- a/exercises/concept/interest-is-interesting/.docs/introduction.md +++ b/exercises/concept/interest-is-interesting/.docs/introduction.md @@ -84,7 +84,7 @@ In contrast, the keyword `continue` only stops the execution of the current iter ```cpp int equal_sum{0}; for (int i{1}; i < 7; ++i) { - if (n%2 == 1) { + if (i%2 == 1) { continue; } equal_sum += i; From 8ffd908fab823412b878e33b988cd64a6c94ce01 Mon Sep 17 00:00:00 2001 From: Christian Willner <34183939+vaeng@users.noreply.github.com> Date: Thu, 4 Jul 2024 17:51:30 +0200 Subject: [PATCH 019/101] chore: update docs for July 2024 (#890) --- .../bank-account/.docs/instructions.md | 2 +- .../practice/darts/.docs/instructions.md | 4 +-- exercises/practice/darts/.meta/config.json | 2 +- .../matching-brackets/.docs/instructions.md | 3 +- .../matching-brackets/.docs/introduction.md | 8 +++++ .../.docs/instructions.md | 2 +- .../pascals-triangle/.docs/instructions.md | 27 ++++++++++++++-- .../pascals-triangle/.docs/introduction.md | 22 +++++++++++++ .../practice/pig-latin/.docs/instructions.md | 4 +-- .../resistor-color-duo/.docs/instructions.md | 2 +- .../practice/space-age/.docs/instructions.md | 31 ++++++++++-------- .../practice/space-age/.docs/introduction.md | 20 ++++++++++++ .../practice/two-bucket/.docs/instructions.md | 2 +- exercises/practice/yacht/.meta/config.json | 2 +- .../zebra-puzzle/.docs/instructions.md | 32 +++++++++++++++++-- .../zebra-puzzle/.docs/introduction.md | 31 +++++++----------- 16 files changed, 143 insertions(+), 51 deletions(-) create mode 100644 exercises/practice/matching-brackets/.docs/introduction.md create mode 100644 exercises/practice/pascals-triangle/.docs/introduction.md create mode 100644 exercises/practice/space-age/.docs/introduction.md diff --git a/exercises/practice/bank-account/.docs/instructions.md b/exercises/practice/bank-account/.docs/instructions.md index 0955520b..7398fbea 100644 --- a/exercises/practice/bank-account/.docs/instructions.md +++ b/exercises/practice/bank-account/.docs/instructions.md @@ -3,7 +3,7 @@ Your task is to implement bank accounts supporting opening/closing, withdrawals, and deposits of money. As bank accounts can be accessed in many different ways (internet, mobile phones, automatic charges), your bank software must allow accounts to be safely accessed from multiple threads/processes (terminology depends on your programming language) in parallel. -For example, there may be many deposits and withdrawals occurring in parallel; you need to ensure there is no [race conditions][wikipedia] between when you read the account balance and set the new balance. +For example, there may be many deposits and withdrawals occurring in parallel; you need to ensure there are no [race conditions][wikipedia] between when you read the account balance and set the new balance. It should be possible to close an account; operations against a closed account must fail. diff --git a/exercises/practice/darts/.docs/instructions.md b/exercises/practice/darts/.docs/instructions.md index 5e57a860..6518201c 100644 --- a/exercises/practice/darts/.docs/instructions.md +++ b/exercises/practice/darts/.docs/instructions.md @@ -1,6 +1,6 @@ # Instructions -Write a function that returns the earned points in a single toss of a Darts game. +Calculate the points scored in a single toss of a Darts game. [Darts][darts] is a game where players throw darts at a [target][darts-target]. @@ -16,7 +16,7 @@ In our particular instance of the game, the target rewards 4 different amounts o The outer circle has a radius of 10 units (this is equivalent to the total radius for the entire target), the middle circle a radius of 5 units, and the inner circle a radius of 1. Of course, they are all centered at the same point — that is, the circles are [concentric][] defined by the coordinates (0, 0). -Write a function that given a point in the target (defined by its [Cartesian coordinates][cartesian-coordinates] `x` and `y`, where `x` and `y` are [real][real-numbers]), returns the correct amount earned by a dart landing at that point. +Given a point in the target (defined by its [Cartesian coordinates][cartesian-coordinates] `x` and `y`, where `x` and `y` are [real][real-numbers]), calculate the correct score earned by a dart landing at that point. ## Credit diff --git a/exercises/practice/darts/.meta/config.json b/exercises/practice/darts/.meta/config.json index 0db74a84..e4f5de8d 100644 --- a/exercises/practice/darts/.meta/config.json +++ b/exercises/practice/darts/.meta/config.json @@ -18,6 +18,6 @@ ".meta/example.h" ] }, - "blurb": "Write a function that returns the earned points in a single toss of a Darts game.", + "blurb": "Calculate the points scored in a single toss of a Darts game.", "source": "Inspired by an exercise created by a professor Della Paolera in Argentina" } diff --git a/exercises/practice/matching-brackets/.docs/instructions.md b/exercises/practice/matching-brackets/.docs/instructions.md index 544daa96..ea170842 100644 --- a/exercises/practice/matching-brackets/.docs/instructions.md +++ b/exercises/practice/matching-brackets/.docs/instructions.md @@ -1,4 +1,5 @@ # Instructions Given a string containing brackets `[]`, braces `{}`, parentheses `()`, or any combination thereof, verify that any and all pairs are matched and nested correctly. -The string may also contain other characters, which for the purposes of this exercise should be ignored. +Any other characters should be ignored. +For example, `"{what is (42)}?"` is balanced and `"[text}"` is not. diff --git a/exercises/practice/matching-brackets/.docs/introduction.md b/exercises/practice/matching-brackets/.docs/introduction.md new file mode 100644 index 00000000..0618221b --- /dev/null +++ b/exercises/practice/matching-brackets/.docs/introduction.md @@ -0,0 +1,8 @@ +# Introduction + +You're given the opportunity to write software for the Bracketeer™, an ancient but powerful mainframe. +The software that runs on it is written in a proprietary language. +Much of its syntax is familiar, but you notice _lots_ of brackets, braces and parentheses. +Despite the Bracketeer™ being powerful, it lacks flexibility. +If the source code has any unbalanced brackets, braces or parentheses, the Bracketeer™ crashes and must be rebooted. +To avoid such a scenario, you start writing code that can verify that brackets, braces, and parentheses are balanced before attempting to run it on the Bracketeer™. diff --git a/exercises/practice/parallel-letter-frequency/.docs/instructions.md b/exercises/practice/parallel-letter-frequency/.docs/instructions.md index 85abcf86..6147b90a 100644 --- a/exercises/practice/parallel-letter-frequency/.docs/instructions.md +++ b/exercises/practice/parallel-letter-frequency/.docs/instructions.md @@ -4,4 +4,4 @@ Count the frequency of letters in texts using parallel computation. Parallelism is about doing things in parallel that can also be done sequentially. A common example is counting the frequency of letters. -Create a function that returns the total frequency of each letter in a list of texts and that employs parallelism. +Employ parallelism to calculate the total frequency of each letter in a list of texts. diff --git a/exercises/practice/pascals-triangle/.docs/instructions.md b/exercises/practice/pascals-triangle/.docs/instructions.md index f5567859..0f58f006 100644 --- a/exercises/practice/pascals-triangle/.docs/instructions.md +++ b/exercises/practice/pascals-triangle/.docs/instructions.md @@ -1,8 +1,20 @@ # Instructions -Compute Pascal's triangle up to a given number of rows. +Your task is to output the first N rows of Pascal's triangle. -In Pascal's Triangle each number is computed by adding the numbers to the right and left of the current position in the previous row. +[Pascal's triangle][wikipedia] is a triangular array of positive integers. + +In Pascal's triangle, the number of values in a row is equal to its row number (which starts at one). +Therefore, the first row has one value, the second row has two values, and so on. + +The first (topmost) row has a single value: `1`. +Subsequent rows' values are computed by adding the numbers directly to the right and left of the current position in the previous row. + +If the previous row does _not_ have a value to the left or right of the current position (which only happens for the leftmost and rightmost positions), treat that position's value as zero (effectively "ignoring" it in the summation). + +## Example + +Let's look at the first 5 rows of Pascal's Triangle: ```text 1 @@ -10,5 +22,14 @@ In Pascal's Triangle each number is computed by adding the numbers to the right 1 2 1 1 3 3 1 1 4 6 4 1 -# ... etc ``` + +The topmost row has one value, which is `1`. + +The leftmost and rightmost values have only one preceding position to consider, which is the position to its right respectively to its left. +With the topmost value being `1`, it follows from this that all the leftmost and rightmost values are also `1`. + +The other values all have two positions to consider. +For example, the fifth row's (`1 4 6 4 1`) middle value is `6`, as the values to its left and right in the preceding row are `3` and `3`: + +[wikipedia]: https://en.wikipedia.org/wiki/Pascal%27s_triangle diff --git a/exercises/practice/pascals-triangle/.docs/introduction.md b/exercises/practice/pascals-triangle/.docs/introduction.md new file mode 100644 index 00000000..60b8ec30 --- /dev/null +++ b/exercises/practice/pascals-triangle/.docs/introduction.md @@ -0,0 +1,22 @@ +# Introduction + +With the weather being great, you're not looking forward to spending an hour in a classroom. +Annoyed, you enter the class room, where you notice a strangely satisfying triangle shape on the blackboard. +Whilst waiting for your math teacher to arrive, you can't help but notice some patterns in the triangle: the outer values are all ones, each subsequent row has one more value than its previous row and the triangle is symmetrical. +Weird! + +Not long after you sit down, your teacher enters the room and explains that this triangle is the famous [Pascal's triangle][wikipedia]. + +Over the next hour, your teacher reveals some amazing things hidden in this triangle: + +- It can be used to compute how many ways you can pick K elements from N values. +- It contains the Fibonacci sequence. +- If you color odd and even numbers differently, you get a beautiful pattern called the [Sierpiński triangle][wikipedia-sierpinski-triangle]. + +The teacher implores you and your classmates to lookup other uses, and assures you that there are lots more! +At that moment, the school bell rings. +You realize that for the past hour, you were completely absorbed in learning about Pascal's triangle. +You quickly grab your laptop from your bag and go outside, ready to enjoy both the sunshine _and_ the wonders of Pascal's triangle. + +[wikipedia]: https://en.wikipedia.org/wiki/Pascal%27s_triangle +[wikipedia-sierpinski-triangle]: https://en.wikipedia.org/wiki/Sierpi%C5%84ski_triangle diff --git a/exercises/practice/pig-latin/.docs/instructions.md b/exercises/practice/pig-latin/.docs/instructions.md index 6c843080..a9645ac2 100644 --- a/exercises/practice/pig-latin/.docs/instructions.md +++ b/exercises/practice/pig-latin/.docs/instructions.md @@ -19,7 +19,7 @@ For example: ## Rule 2 -If a word begins with a one or more consonants, first move those consonants to the end of the word and then add an `"ay"` sound to the end of the word. +If a word begins with one or more consonants, first move those consonants to the end of the word and then add an `"ay"` sound to the end of the word. For example: @@ -33,7 +33,7 @@ If a word starts with zero or more consonants followed by `"qu"`, first move tho For example: -- `"quick"` -> `"ickqu"` -> `"ay"` (starts with `"qu"`, no preceding consonants) +- `"quick"` -> `"ickqu"` -> `"ickquay"` (starts with `"qu"`, no preceding consonants) - `"square"` -> `"aresqu"` -> `"aresquay"` (starts with one consonant followed by `"qu`") ## Rule 4 diff --git a/exercises/practice/resistor-color-duo/.docs/instructions.md b/exercises/practice/resistor-color-duo/.docs/instructions.md index bdcd549b..18ee4078 100644 --- a/exercises/practice/resistor-color-duo/.docs/instructions.md +++ b/exercises/practice/resistor-color-duo/.docs/instructions.md @@ -29,5 +29,5 @@ The band colors are encoded as follows: - White: 9 From the example above: -brown-green should return 15 +brown-green should return 15, and brown-green-violet should return 15 too, ignoring the third color. diff --git a/exercises/practice/space-age/.docs/instructions.md b/exercises/practice/space-age/.docs/instructions.md index fe938cc0..f23b5e2c 100644 --- a/exercises/practice/space-age/.docs/instructions.md +++ b/exercises/practice/space-age/.docs/instructions.md @@ -1,25 +1,28 @@ # Instructions -Given an age in seconds, calculate how old someone would be on: +Given an age in seconds, calculate how old someone would be on a planet in our Solar System. -- Mercury: orbital period 0.2408467 Earth years -- Venus: orbital period 0.61519726 Earth years -- Earth: orbital period 1.0 Earth years, 365.25 Earth days, or 31557600 seconds -- Mars: orbital period 1.8808158 Earth years -- Jupiter: orbital period 11.862615 Earth years -- Saturn: orbital period 29.447498 Earth years -- Uranus: orbital period 84.016846 Earth years -- Neptune: orbital period 164.79132 Earth years +One Earth year equals 365.25 Earth days, or 31,557,600 seconds. +If you were told someone was 1,000,000,000 seconds old, their age would be 31.69 Earth-years. -So if you were told someone were 1,000,000,000 seconds old, you should -be able to say that they're 31.69 Earth-years old. +For the other planets, you have to account for their orbital period in Earth Years: -If you're wondering why Pluto didn't make the cut, go watch [this YouTube video][pluto-video]. +| Planet | Orbital period in Earth Years | +| ------- | ----------------------------- | +| Mercury | 0.2408467 | +| Venus | 0.61519726 | +| Earth | 1.0 | +| Mars | 1.8808158 | +| Jupiter | 11.862615 | +| Saturn | 29.447498 | +| Uranus | 84.016846 | +| Neptune | 164.79132 | -Note: The actual length of one complete orbit of the Earth around the sun is closer to 365.256 days (1 sidereal year). +~~~~exercism/note +The actual length of one complete orbit of the Earth around the sun is closer to 365.256 days (1 sidereal year). The Gregorian calendar has, on average, 365.2425 days. While not entirely accurate, 365.25 is the value used in this exercise. See [Year on Wikipedia][year] for more ways to measure a year. -[pluto-video]: https://www.youtube.com/watch?v=Z_2gbGXzFbs [year]: https://en.wikipedia.org/wiki/Year#Summary +~~~~ diff --git a/exercises/practice/space-age/.docs/introduction.md b/exercises/practice/space-age/.docs/introduction.md new file mode 100644 index 00000000..014d7885 --- /dev/null +++ b/exercises/practice/space-age/.docs/introduction.md @@ -0,0 +1,20 @@ +# Introduction + +The year is 2525 and you've just embarked on a journey to visit all planets in the Solar System (Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus and Neptune). +The first stop is Mercury, where customs require you to fill out a form (bureaucracy is apparently _not_ Earth-specific). +As you hand over the form to the customs officer, they scrutinize it and frown. +"Do you _really_ expect me to believe you're just 50 years old? +You must be closer to 200 years old!" + +Amused, you wait for the customs officer to start laughing, but they appear to be dead serious. +You realize that you've entered your age in _Earth years_, but the officer expected it in _Mercury years_! +As Mercury's orbital period around the sun is significantly shorter than Earth, you're actually a lot older in Mercury years. +After some quick calculations, you're able to provide your age in Mercury Years. +The customs officer smiles, satisfied, and waves you through. +You make a mental note to pre-calculate your planet-specific age _before_ future customs checks, to avoid such mix-ups. + +~~~~exercism/note +If you're wondering why Pluto didn't make the cut, go watch [this YouTube video][pluto-video]. + +[pluto-video]: https://www.youtube.com/watch?v=Z_2gbGXzFbs +~~~~ diff --git a/exercises/practice/two-bucket/.docs/instructions.md b/exercises/practice/two-bucket/.docs/instructions.md index 7249deb3..30d779aa 100644 --- a/exercises/practice/two-bucket/.docs/instructions.md +++ b/exercises/practice/two-bucket/.docs/instructions.md @@ -11,7 +11,7 @@ There are some rules that your solution must follow: b) the second bucket is full 2. Emptying a bucket and doing nothing to the other. 3. Filling a bucket and doing nothing to the other. -- After an action, you may not arrive at a state where the starting bucket is empty and the other bucket is full. +- After an action, you may not arrive at a state where the initial starting bucket is empty and the other bucket is full. Your program will take as input: diff --git a/exercises/practice/yacht/.meta/config.json b/exercises/practice/yacht/.meta/config.json index a3c2769a..e3434a29 100644 --- a/exercises/practice/yacht/.meta/config.json +++ b/exercises/practice/yacht/.meta/config.json @@ -16,6 +16,6 @@ ] }, "blurb": "Score a single throw of dice in the game Yacht.", - "source": "James Kilfiger, using wikipedia", + "source": "James Kilfiger, using Wikipedia", "source_url": "https://en.wikipedia.org/wiki/Yacht_(dice_game)" } diff --git a/exercises/practice/zebra-puzzle/.docs/instructions.md b/exercises/practice/zebra-puzzle/.docs/instructions.md index c435573e..aedce9b2 100644 --- a/exercises/practice/zebra-puzzle/.docs/instructions.md +++ b/exercises/practice/zebra-puzzle/.docs/instructions.md @@ -1,6 +1,32 @@ # Instructions -Your task is to solve the ‘Zebra Puzzle’ also known as ‘The Einstein's Puzzle’ but how you do it that depends on you, best way to solve this problem is first you solve it with your pen and paper, it will take time but it will improve your logical thinking and its provide programmatic way to solve this problem. +Your task is to solve the Zebra Puzzle to find the answer to these two questions: -**!!Spoiler warning!!** -You can learn more about this problem on [Zebra Puzzle](https://en.wikipedia.org/wiki/Zebra_Puzzle) +- Which of the residents drinks water? +- Who owns the zebra? + +## Puzzle + +The following 15 statements are all known to be true: + +1. There are five houses. +2. The Englishman lives in the red house. +3. The Spaniard owns the dog. +4. The person in the green house drinks coffee. +5. The Ukrainian drinks tea. +6. The green house is immediately to the right of the ivory house. +7. The snail owner likes to go dancing. +8. The person in the yellow house is a painter. +9. The person in the middle house drinks milk. +10. The Norwegian lives in the first house. +11. The person who enjoys reading lives in the house next to the person with the fox. +12. The painter's house is next to the house with the horse. +13. The person who plays football drinks orange juice. +14. The Japanese person plays chess. +15. The Norwegian lives next to the blue house. + +Additionally, each of the five houses is painted a different color, and their inhabitants are of different national extractions, own different pets, drink different beverages and engage in different hobbies. + +~~~~exercism/note +There are 24 billion (5!⁵ = 24,883,200,000) possible solutions, so try ruling out as many solutions as possible. +~~~~ diff --git a/exercises/practice/zebra-puzzle/.docs/introduction.md b/exercises/practice/zebra-puzzle/.docs/introduction.md index 6d62d18e..bbcaa6fd 100644 --- a/exercises/practice/zebra-puzzle/.docs/introduction.md +++ b/exercises/practice/zebra-puzzle/.docs/introduction.md @@ -1,24 +1,15 @@ -# Instructions +# Introduction -Solve the zebra puzzle. +The Zebra Puzzle is a famous logic puzzle in which there are five houses, each painted a different color. +The houses have different inhabitants, who have different nationalities, own different pets, drink different beverages and enjoy different hobbies. -1. There are five houses. -2. The Englishman lives in the red house. -3. The Spaniard owns the dog. -4. Coffee is drunk in the green house. -5. The Ukrainian drinks tea. -6. The green house is immediately to the right of the ivory house. -7. The Old Gold smoker owns snails. -8. Kools are smoked in the yellow house. -9. Milk is drunk in the middle house. -10. The Norwegian lives in the first house. -11. The man who smokes Chesterfields lives in the house next to the man with the fox. -12. Kools are smoked in the house next to the house where the horse is kept. -13. The Lucky Strike smoker drinks orange juice. -14. The Japanese smokes Parliaments. -15. The Norwegian lives next to the blue house. +To help you solve the puzzle, you're given 15 statements describing the solution. +However, only by combining the information in _all_ statements will you be able to find the solution to the puzzle. -Each of the five houses is painted a different color, and their inhabitants are of different national extractions, own different pets, drink different beverages and smoke different brands of cigarettes. +~~~~exercism/note +The Zebra Puzzle is a [Constraint satisfaction problem (CSP)][constraint-satisfaction-problem]. +In such a problem, you have a set of possible values and a set of constraints that limit which values are valid. +Another well-known CSP is Sudoku. -Which of the residents drinks water? -Who owns the zebra? +[constraint-satisfaction-problem]: https://en.wikipedia.org/wiki/Constraint_satisfaction_problem +~~~~ From 02c3a12ac60e5530ff4b46cf986999f3bdd48f22 Mon Sep 17 00:00:00 2001 From: Alexey Klimkin Date: Sat, 6 Jul 2024 12:58:05 -0700 Subject: [PATCH 020/101] feat: add practice exercise Rail Fence Cipher (#881) --- config.json | 16 + .../rail-fence-cipher/.docs/instructions.md | 57 + .../rail-fence-cipher/.meta/config.json | 21 + .../rail-fence-cipher/.meta/example.cpp | 49 + .../rail-fence-cipher/.meta/example.h | 10 + .../rail-fence-cipher/.meta/tests.toml | 28 + .../practice/rail-fence-cipher/CMakeLists.txt | 64 + .../rail-fence-cipher/rail_fence_cipher.cpp | 9 + .../rail-fence-cipher/rail_fence_cipher.h | 10 + .../rail_fence_cipher_test.cpp | 42 + .../practice/rail-fence-cipher/test/catch.hpp | 17937 ++++++++++++++++ .../rail-fence-cipher/test/tests-main.cpp | 2 + 12 files changed, 18245 insertions(+) create mode 100644 exercises/practice/rail-fence-cipher/.docs/instructions.md create mode 100644 exercises/practice/rail-fence-cipher/.meta/config.json create mode 100644 exercises/practice/rail-fence-cipher/.meta/example.cpp create mode 100644 exercises/practice/rail-fence-cipher/.meta/example.h create mode 100644 exercises/practice/rail-fence-cipher/.meta/tests.toml create mode 100644 exercises/practice/rail-fence-cipher/CMakeLists.txt create mode 100644 exercises/practice/rail-fence-cipher/rail_fence_cipher.cpp create mode 100644 exercises/practice/rail-fence-cipher/rail_fence_cipher.h create mode 100644 exercises/practice/rail-fence-cipher/rail_fence_cipher_test.cpp create mode 100644 exercises/practice/rail-fence-cipher/test/catch.hpp create mode 100644 exercises/practice/rail-fence-cipher/test/tests-main.cpp diff --git a/config.json b/config.json index 935751bf..b47885cc 100644 --- a/config.json +++ b/config.json @@ -1206,6 +1206,22 @@ "practices": [], "prerequisites": [], "difficulty": 4 + }, + { + "slug": "rail-fence-cipher", + "name": "Rail Fence Cipher", + "uuid": "8a7f6f8c-ff36-4afd-9ab3-6dbd355d0263", + "practices": [], + "prerequisites": [ + "basics", + "namespaces", + "conditionals", + "lists", + "loops", + "numbers", + "strings" + ], + "difficulty": 4 } ], "foregone": [ diff --git a/exercises/practice/rail-fence-cipher/.docs/instructions.md b/exercises/practice/rail-fence-cipher/.docs/instructions.md new file mode 100644 index 00000000..e311de6c --- /dev/null +++ b/exercises/practice/rail-fence-cipher/.docs/instructions.md @@ -0,0 +1,57 @@ +# Instructions + +Implement encoding and decoding for the rail fence cipher. + +The Rail Fence cipher is a form of transposition cipher that gets its name from the way in which it's encoded. +It was already used by the ancient Greeks. + +In the Rail Fence cipher, the message is written downwards on successive "rails" of an imaginary fence, then moving up when we get to the bottom (like a zig-zag). +Finally the message is then read off in rows. + +For example, using three "rails" and the message "WE ARE DISCOVERED FLEE AT ONCE", the cipherer writes out: + +```text +W . . . E . . . C . . . R . . . L . . . T . . . E +. E . R . D . S . O . E . E . F . E . A . O . C . +. . A . . . I . . . V . . . D . . . E . . . N . . +``` + +Then reads off: + +```text +WECRLTEERDSOEEFEAOCAIVDEN +``` + +To decrypt a message you take the zig-zag shape and fill the ciphertext along the rows. + +```text +? . . . ? . . . ? . . . ? . . . ? . . . ? . . . ? +. ? . ? . ? . ? . ? . ? . ? . ? . ? . ? . ? . ? . +. . ? . . . ? . . . ? . . . ? . . . ? . . . ? . . +``` + +The first row has seven spots that can be filled with "WECRLTE". + +```text +W . . . E . . . C . . . R . . . L . . . T . . . E +. ? . ? . ? . ? . ? . ? . ? . ? . ? . ? . ? . ? . +. . ? . . . ? . . . ? . . . ? . . . ? . . . ? . . +``` + +Now the 2nd row takes "ERDSOEEFEAOC". + +```text +W . . . E . . . C . . . R . . . L . . . T . . . E +. E . R . D . S . O . E . E . F . E . A . O . C . +. . ? . . . ? . . . ? . . . ? . . . ? . . . ? . . +``` + +Leaving "AIVDEN" for the last row. + +```text +W . . . E . . . C . . . R . . . L . . . T . . . E +. E . R . D . S . O . E . E . F . E . A . O . C . +. . A . . . I . . . V . . . D . . . E . . . N . . +``` + +If you now read along the zig-zag shape you can read the original message. diff --git a/exercises/practice/rail-fence-cipher/.meta/config.json b/exercises/practice/rail-fence-cipher/.meta/config.json new file mode 100644 index 00000000..daeac32a --- /dev/null +++ b/exercises/practice/rail-fence-cipher/.meta/config.json @@ -0,0 +1,21 @@ +{ + "authors": [ + "klimkin" + ], + "files": { + "solution": [ + "rail_fence_cipher.cpp", + "rail_fence_cipher.h" + ], + "test": [ + "rail_fence_cipher_test.cpp" + ], + "example": [ + ".meta/example.cpp", + ".meta/example.h" + ] + }, + "blurb": "Implement encoding and decoding for the rail fence cipher.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Transposition_cipher#Rail_Fence_cipher" +} diff --git a/exercises/practice/rail-fence-cipher/.meta/example.cpp b/exercises/practice/rail-fence-cipher/.meta/example.cpp new file mode 100644 index 00000000..8d095d2a --- /dev/null +++ b/exercises/practice/rail-fence-cipher/.meta/example.cpp @@ -0,0 +1,49 @@ +#include "rail_fence_cipher.h" + +namespace rail_fence_cipher { + +std::string encode(const std::string& plaintext, int num_rails) { + if (num_rails <= 1) return plaintext; + + const auto stride = num_rails * 2 - 2; + const auto length = plaintext.size(); + + std::string result(length, ' '); + auto dst = result.begin(); + + for (int rail = 0; rail < num_rails; ++rail) { + for (size_t pos = rail; pos < length; pos += stride) { + *dst++ = plaintext[pos]; + if (0 < rail && rail < num_rails - 1) { + size_t next_pos = pos + stride - rail * 2; + if (next_pos < length) *dst++ = plaintext[next_pos]; + } + } + } + + return result; +} + +std::string decode(const std::string& ciphertext, int num_rails) { + if (num_rails <= 1) return ciphertext; + + const auto stride = num_rails * 2 - 2; + const auto length = ciphertext.size(); + + std::string result(length, ' '); + auto src = ciphertext.cbegin(); + + for (int rail = 0; rail < num_rails; ++rail) { + for (size_t pos = rail; pos < length; pos += stride) { + result[pos] = *src++; + if (0 < rail && rail < num_rails - 1) { + size_t next_pos = pos + stride - rail * 2; + if (next_pos < length) result[next_pos] = *src++; + } + } + } + + return result; +} + +} // namespace rail_fence_cipher diff --git a/exercises/practice/rail-fence-cipher/.meta/example.h b/exercises/practice/rail-fence-cipher/.meta/example.h new file mode 100644 index 00000000..528bc925 --- /dev/null +++ b/exercises/practice/rail-fence-cipher/.meta/example.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace rail_fence_cipher { + +std::string encode(const std::string& plaintext, int num_rails); +std::string decode(const std::string& ciphertext, int num_rails); + +} // namespace rail_fence_cipher diff --git a/exercises/practice/rail-fence-cipher/.meta/tests.toml b/exercises/practice/rail-fence-cipher/.meta/tests.toml new file mode 100644 index 00000000..dfc5e16b --- /dev/null +++ b/exercises/practice/rail-fence-cipher/.meta/tests.toml @@ -0,0 +1,28 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[46dc5c50-5538-401d-93a5-41102680d068] +description = "encode -> encode with two rails" + +[25691697-fbd8-4278-8c38-b84068b7bc29] +description = "encode -> encode with three rails" + +[384f0fea-1442-4f1a-a7c4-5cbc2044002c] +description = "encode -> encode with ending in the middle" + +[cd525b17-ec34-45ef-8f0e-4f27c24a7127] +description = "decode -> decode with three rails" + +[dd7b4a98-1a52-4e5c-9499-cbb117833507] +description = "decode -> decode with five rails" + +[93e1ecf4-fac9-45d9-9cd2-591f47d3b8d3] +description = "decode -> decode with six rails" diff --git a/exercises/practice/rail-fence-cipher/CMakeLists.txt b/exercises/practice/rail-fence-cipher/CMakeLists.txt new file mode 100644 index 00000000..3b0589fd --- /dev/null +++ b/exercises/practice/rail-fence-cipher/CMakeLists.txt @@ -0,0 +1,64 @@ +# Get the exercise name from the current directory +get_filename_component(exercise ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +# Basic CMake project +cmake_minimum_required(VERSION 3.5.1) + +# Name the project after the exercise +project(${exercise} CXX) + +# Get a source filename from the exercise name by replacing -'s with _'s +string(REPLACE "-" "_" file ${exercise}) + +# Implementation could be only a header +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.cpp) + set(exercise_cpp ${file}.cpp) +else() + set(exercise_cpp "") +endif() + +# Use the common Catch library? +if(EXERCISM_COMMON_CATCH) + # For Exercism track development only + add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h $) +elseif(EXERCISM_TEST_SUITE) + # The Exercism test suite is being run, the Docker image already + # includes a pre-built version of Catch. + find_package(Catch2 REQUIRED) + add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h) + target_link_libraries(${exercise} PRIVATE Catch2::Catch2WithMain) + # When Catch is installed system wide we need to include a different + # header, we need this define to use the correct one. + target_compile_definitions(${exercise} PRIVATE EXERCISM_TEST_SUITE) +else() + # Build executable from sources and headers + add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h test/tests-main.cpp) +endif() + +set_target_properties(${exercise} PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED OFF + CXX_EXTENSIONS OFF +) + +set(CMAKE_BUILD_TYPE Debug) + +if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(GNU|Clang)") + set_target_properties(${exercise} PROPERTIES + COMPILE_FLAGS "-Wall -Wextra -Wpedantic -Werror" + ) +endif() + +# Configure to run all the tests? +if(${EXERCISM_RUN_ALL_TESTS}) + target_compile_definitions(${exercise} PRIVATE EXERCISM_RUN_ALL_TESTS) +endif() + +# Tell MSVC not to warn us about unchecked iterators in debug builds +if(${MSVC}) + set_target_properties(${exercise} PROPERTIES + COMPILE_DEFINITIONS_DEBUG _SCL_SECURE_NO_WARNINGS) +endif() + +# Run the tests on every build +add_custom_target(test_${exercise} ALL DEPENDS ${exercise} COMMAND ${exercise}) diff --git a/exercises/practice/rail-fence-cipher/rail_fence_cipher.cpp b/exercises/practice/rail-fence-cipher/rail_fence_cipher.cpp new file mode 100644 index 00000000..01b0f78a --- /dev/null +++ b/exercises/practice/rail-fence-cipher/rail_fence_cipher.cpp @@ -0,0 +1,9 @@ +#include "rail_fence_cipher.h" + +namespace rail_fence_cipher { + +std::string encode(const std::string& plaintext, int num_rails) {} + +std::string decode(const std::string& ciphertext, int num_rails) {} + +} // namespace rail_fence_cipher diff --git a/exercises/practice/rail-fence-cipher/rail_fence_cipher.h b/exercises/practice/rail-fence-cipher/rail_fence_cipher.h new file mode 100644 index 00000000..528bc925 --- /dev/null +++ b/exercises/practice/rail-fence-cipher/rail_fence_cipher.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace rail_fence_cipher { + +std::string encode(const std::string& plaintext, int num_rails); +std::string decode(const std::string& ciphertext, int num_rails); + +} // namespace rail_fence_cipher diff --git a/exercises/practice/rail-fence-cipher/rail_fence_cipher_test.cpp b/exercises/practice/rail-fence-cipher/rail_fence_cipher_test.cpp new file mode 100644 index 00000000..d8b161e7 --- /dev/null +++ b/exercises/practice/rail-fence-cipher/rail_fence_cipher_test.cpp @@ -0,0 +1,42 @@ +#include "rail_fence_cipher.h" +#ifdef EXERCISM_TEST_SUITE +#include +#else +#include "test/catch.hpp" +#endif + +TEST_CASE("encode with two rails", "[46dc5c50-5538-401d-93a5-41102680d068]") { + REQUIRE(rail_fence_cipher::encode("XOXOXOXOXOXOXOXOXO", 2) == + "XXXXXXXXXOOOOOOOOO"); +} + +#if defined(EXERCISM_RUN_ALL_TESTS) + +TEST_CASE("encode with three rails", "[25691697-fbd8-4278-8c38-b84068b7bc29]") { + REQUIRE(rail_fence_cipher::encode("WEAREDISCOVEREDFLEEATONCE", 3) == + "WECRLTEERDSOEEFEAOCAIVDEN"); +} + +TEST_CASE("encode with ending in the middle", + "[384f0fea-1442-4f1a-a7c4-5cbc2044002c]") { + REQUIRE(rail_fence_cipher::encode("EXERCISES", 4) == "ESXIEECSR"); +} + +TEST_CASE("decode_with_three_rails", "[cd525b17-ec34-45ef-8f0e-4f27c24a7127]") { + REQUIRE(rail_fence_cipher::decode("TEITELHDVLSNHDTISEIIEA", 3) == + "THEDEVILISINTHEDETAILS"); +} + +TEST_CASE("decode_with_five_rails", "[dd7b4a98-1a52-4e5c-9499-cbb117833507]") { + REQUIRE(rail_fence_cipher::decode("EIEXMSMESAORIWSCE", 5) == + "EXERCISMISAWESOME"); +} + +TEST_CASE("decode_with_six_rails", "[93e1ecf4-fac9-45d9-9cd2-591f47d3b8d3]") { + REQUIRE(rail_fence_cipher::decode( + "133714114238148966225439541018335470986172518171757571896261", + 6) == + "112358132134558914423337761098715972584418167651094617711286"); +} + +#endif diff --git a/exercises/practice/rail-fence-cipher/test/catch.hpp b/exercises/practice/rail-fence-cipher/test/catch.hpp new file mode 100644 index 00000000..36eaeb27 --- /dev/null +++ b/exercises/practice/rail-fence-cipher/test/catch.hpp @@ -0,0 +1,17937 @@ +/* + * Catch v2.13.6 + * Generated: 2021-04-16 18:23:38.044268 + * ---------------------------------------------------------- + * This file has been merged from multiple headers. Please don't edit it directly + * Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +// start catch.hpp + + +#define CATCH_VERSION_MAJOR 2 +#define CATCH_VERSION_MINOR 13 +#define CATCH_VERSION_PATCH 6 + +#ifdef __clang__ +# pragma clang system_header +#elif defined __GNUC__ +# pragma GCC system_header +#endif + +// start catch_suppress_warnings.h + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(push) +# pragma warning(disable: 161 1682) +# else // __ICC +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wcovered-switch-default" +# endif +#elif defined __GNUC__ + // Because REQUIREs trigger GCC's -Wparentheses, and because still + // supported version of g++ have only buggy support for _Pragmas, + // Wparentheses have to be suppressed globally. +# pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details + +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-variable" +# pragma GCC diagnostic ignored "-Wpadded" +#endif +// end catch_suppress_warnings.h +#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) +# define CATCH_IMPL +# define CATCH_CONFIG_ALL_PARTS +#endif + +// In the impl file, we want to have access to all parts of the headers +// Can also be used to sanely support PCHs +#if defined(CATCH_CONFIG_ALL_PARTS) +# define CATCH_CONFIG_EXTERNAL_INTERFACES +# if defined(CATCH_CONFIG_DISABLE_MATCHERS) +# undef CATCH_CONFIG_DISABLE_MATCHERS +# endif +# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +# endif +#endif + +#if !defined(CATCH_CONFIG_IMPL_ONLY) +// start catch_platform.h + +// See e.g.: +// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html +#ifdef __APPLE__ +# include +# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ + (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) +# define CATCH_PLATFORM_MAC +# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) +# define CATCH_PLATFORM_IPHONE +# endif + +#elif defined(linux) || defined(__linux) || defined(__linux__) +# define CATCH_PLATFORM_LINUX + +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) +# define CATCH_PLATFORM_WINDOWS +#endif + +// end catch_platform.h + +#ifdef CATCH_IMPL +# ifndef CLARA_CONFIG_MAIN +# define CLARA_CONFIG_MAIN_NOT_DEFINED +# define CLARA_CONFIG_MAIN +# endif +#endif + +// start catch_user_interfaces.h + +namespace Catch { + unsigned int rngSeed(); +} + +// end catch_user_interfaces.h +// start catch_tag_alias_autoregistrar.h + +// start catch_common.h + +// start catch_compiler_capabilities.h + +// Detect a number of compiler features - by compiler +// The following features are defined: +// +// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? +// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? +// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? +// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? +// **************** +// Note to maintainers: if new toggles are added please document them +// in configuration.md, too +// **************** + +// In general each macro has a _NO_ form +// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +#ifdef __cplusplus + +# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) +# define CATCH_CPP14_OR_GREATER +# endif + +# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +# define CATCH_CPP17_OR_GREATER +# endif + +#endif + +// Only GCC compiler should be used in this block, so other compilers trying to +// mask themselves as GCC should be ignored. +#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) + +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) + +#endif + +#if defined(__clang__) + +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) + +// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug +// which results in calls to destructors being emitted for each temporary, +// without a matching initialization. In practice, this can result in something +// like `std::string::~string` being called on an uninitialized value. +// +// For example, this code will likely segfault under IBM XL: +// ``` +// REQUIRE(std::string("12") + "34" == "1234") +// ``` +// +// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. +# if !defined(__ibmxl__) && !defined(__CUDACC__) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ +# endif + +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ + _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") + +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) + +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// Assume that non-Windows platforms support posix signals by default +#if !defined(CATCH_PLATFORM_WINDOWS) + #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS +#endif + +//////////////////////////////////////////////////////////////////////////////// +// We know some environments not to support full POSIX signals +#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) + #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +#endif + +#ifdef __OS400__ +# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +# define CATCH_CONFIG_COLOUR_NONE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Android somehow still does not support std::to_string +#if defined(__ANDROID__) +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Not all Windows environments support SEH properly +#if defined(__MINGW32__) +# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH +#endif + +//////////////////////////////////////////////////////////////////////////////// +// PS4 +#if defined(__ORBIS__) +# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Cygwin +#ifdef __CYGWIN__ + +// Required for some versions of Cygwin to declare gettimeofday +// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin +# define _BSD_SOURCE +// some versions of cygwin (most) do not support std::to_string. Use the libstd check. +// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 +# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ + && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) + +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING + +# endif +#endif // __CYGWIN__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#if defined(_MSC_VER) + +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) + +// Universal Windows platform does not support SEH +// Or console colours (or console at all...) +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +# define CATCH_CONFIG_COLOUR_NONE +# else +# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH +# endif + +// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ +// _MSVC_TRADITIONAL == 0 means new conformant preprocessor +// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor +# if !defined(__clang__) // Handle Clang masquerading for msvc +# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) +# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +# endif // MSVC_TRADITIONAL +# endif // __clang__ + +#endif // _MSC_VER + +#if defined(_REENTRANT) || defined(_MSC_VER) +// Enable async processing, as -pthread is specified or no additional linking is required +# define CATCH_INTERNAL_CONFIG_USE_ASYNC +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// +// Check if we are compiled with -fno-exceptions or equivalent +#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) +# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED +#endif + +//////////////////////////////////////////////////////////////////////////////// +// DJGPP +#ifdef __DJGPP__ +# define CATCH_INTERNAL_CONFIG_NO_WCHAR +#endif // __DJGPP__ + +//////////////////////////////////////////////////////////////////////////////// +// Embarcadero C++Build +#if defined(__BORLANDC__) + #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN +#endif + +//////////////////////////////////////////////////////////////////////////////// + +// Use of __COUNTER__ is suppressed during code analysis in +// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly +// handled by it. +// Otherwise all supported compilers support COUNTER macro, +// but user still might want to turn it off +#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) + #define CATCH_INTERNAL_CONFIG_COUNTER +#endif + +//////////////////////////////////////////////////////////////////////////////// + +// RTX is a special version of Windows that is real time. +// This means that it is detected as Windows, but does not provide +// the same set of capabilities as real Windows does. +#if defined(UNDER_RTSS) || defined(RTX64_BUILD) + #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH + #define CATCH_INTERNAL_CONFIG_NO_ASYNC + #define CATCH_CONFIG_COLOUR_NONE +#endif + +#if !defined(_GLIBCXX_USE_C99_MATH_TR1) +#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Various stdlib support checks that require __has_include +#if defined(__has_include) + // Check if string_view is available and usable + #if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW + #endif + + // Check if optional is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if byte is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # include + # if __cpp_lib_byte > 0 + # define CATCH_INTERNAL_CONFIG_CPP17_BYTE + # endif + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if variant is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # if defined(__clang__) && (__clang_major__ < 8) + // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 + // fix should be in clang 8, workaround in libstdc++ 8.2 + # include + # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # define CATCH_CONFIG_NO_CPP17_VARIANT + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__clang__) && (__clang_major__ < 8) + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) +#endif // defined(__has_include) + +#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) +# define CATCH_CONFIG_COUNTER +#endif +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) +# define CATCH_CONFIG_WINDOWS_SEH +#endif +// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. +#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_CONFIG_POSIX_SIGNALS +#endif +// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. +#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) +# define CATCH_CONFIG_WCHAR +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) +# define CATCH_CONFIG_CPP11_TO_STRING +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) +# define CATCH_CONFIG_CPP17_OPTIONAL +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) +# define CATCH_CONFIG_CPP17_STRING_VIEW +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) +# define CATCH_CONFIG_CPP17_VARIANT +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) +# define CATCH_CONFIG_CPP17_BYTE +#endif + +#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) +# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) +# define CATCH_CONFIG_NEW_CAPTURE +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +# define CATCH_CONFIG_DISABLE_EXCEPTIONS +#endif + +#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) +# define CATCH_CONFIG_POLYFILL_ISNAN +#endif + +#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) +# define CATCH_CONFIG_USE_ASYNC +#endif + +#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) +# define CATCH_CONFIG_ANDROID_LOGWRITE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) +# define CATCH_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Even if we do not think the compiler has that warning, we still have +// to provide a macro that can be used by the code. +#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS +#endif + +// The goal of this macro is to avoid evaluation of the arguments, but +// still have the compiler warn on problems inside... +#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) +#endif + +#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#elif defined(__clang__) && (__clang_major__ < 5) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +#define CATCH_TRY if ((true)) +#define CATCH_CATCH_ALL if ((false)) +#define CATCH_CATCH_ANON(type) if ((false)) +#else +#define CATCH_TRY try +#define CATCH_CATCH_ALL catch (...) +#define CATCH_CATCH_ANON(type) catch (type) +#endif + +#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) +#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#endif + +// end catch_compiler_capabilities.h +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line +#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) +#ifdef CATCH_CONFIG_COUNTER +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) +#else +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) +#endif + +#include +#include +#include + +// We need a dummy global operator<< so we can bring it into Catch namespace later +struct Catch_global_namespace_dummy {}; +std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); + +namespace Catch { + + struct CaseSensitive { enum Choice { + Yes, + No + }; }; + + class NonCopyable { + NonCopyable( NonCopyable const& ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable& operator = ( NonCopyable const& ) = delete; + NonCopyable& operator = ( NonCopyable && ) = delete; + + protected: + NonCopyable(); + virtual ~NonCopyable(); + }; + + struct SourceLineInfo { + + SourceLineInfo() = delete; + SourceLineInfo( char const* _file, std::size_t _line ) noexcept + : file( _file ), + line( _line ) + {} + + SourceLineInfo( SourceLineInfo const& other ) = default; + SourceLineInfo& operator = ( SourceLineInfo const& ) = default; + SourceLineInfo( SourceLineInfo&& ) noexcept = default; + SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; + + bool empty() const noexcept { return file[0] == '\0'; } + bool operator == ( SourceLineInfo const& other ) const noexcept; + bool operator < ( SourceLineInfo const& other ) const noexcept; + + char const* file; + std::size_t line; + }; + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); + + // Bring in operator<< from global namespace into Catch namespace + // This is necessary because the overload of operator<< above makes + // lookup stop at namespace Catch + using ::operator<<; + + // Use this in variadic streaming macros to allow + // >> +StreamEndStop + // as well as + // >> stuff +StreamEndStop + struct StreamEndStop { + std::string operator+() const; + }; + template + T const& operator + ( T const& value, StreamEndStop ) { + return value; + } +} + +#define CATCH_INTERNAL_LINEINFO \ + ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) + +// end catch_common.h +namespace Catch { + + struct RegistrarForTagAliases { + RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + }; + +} // end namespace Catch + +#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION + +// end catch_tag_alias_autoregistrar.h +// start catch_test_registry.h + +// start catch_interfaces_testcase.h + +#include + +namespace Catch { + + class TestSpec; + + struct ITestInvoker { + virtual void invoke () const = 0; + virtual ~ITestInvoker(); + }; + + class TestCase; + struct IConfig; + + struct ITestCaseRegistry { + virtual ~ITestCaseRegistry(); + virtual std::vector const& getAllTests() const = 0; + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; + }; + + bool isThrowSafe( TestCase const& testCase, IConfig const& config ); + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector const& getAllTestCasesSorted( IConfig const& config ); + +} + +// end catch_interfaces_testcase.h +// start catch_stringref.h + +#include +#include +#include +#include + +namespace Catch { + + /// A non-owning string class (similar to the forthcoming std::string_view) + /// Note that, because a StringRef may be a substring of another string, + /// it may not be null terminated. + class StringRef { + public: + using size_type = std::size_t; + using const_iterator = const char*; + + private: + static constexpr char const* const s_empty = ""; + + char const* m_start = s_empty; + size_type m_size = 0; + + public: // construction + constexpr StringRef() noexcept = default; + + StringRef( char const* rawChars ) noexcept; + + constexpr StringRef( char const* rawChars, size_type size ) noexcept + : m_start( rawChars ), + m_size( size ) + {} + + StringRef( std::string const& stdString ) noexcept + : m_start( stdString.c_str() ), + m_size( stdString.size() ) + {} + + explicit operator std::string() const { + return std::string(m_start, m_size); + } + + public: // operators + auto operator == ( StringRef const& other ) const noexcept -> bool; + auto operator != (StringRef const& other) const noexcept -> bool { + return !(*this == other); + } + + auto operator[] ( size_type index ) const noexcept -> char { + assert(index < m_size); + return m_start[index]; + } + + public: // named queries + constexpr auto empty() const noexcept -> bool { + return m_size == 0; + } + constexpr auto size() const noexcept -> size_type { + return m_size; + } + + // Returns the current start pointer. If the StringRef is not + // null-terminated, throws std::domain_exception + auto c_str() const -> char const*; + + public: // substrings and searches + // Returns a substring of [start, start + length). + // If start + length > size(), then the substring is [start, size()). + // If start > size(), then the substring is empty. + auto substr( size_type start, size_type length ) const noexcept -> StringRef; + + // Returns the current start pointer. May not be null-terminated. + auto data() const noexcept -> char const*; + + constexpr auto isNullTerminated() const noexcept -> bool { + return m_start[m_size] == '\0'; + } + + public: // iterators + constexpr const_iterator begin() const { return m_start; } + constexpr const_iterator end() const { return m_start + m_size; } + }; + + auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; + auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; + + constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { + return StringRef( rawChars, size ); + } +} // namespace Catch + +constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { + return Catch::StringRef( rawChars, size ); +} + +// end catch_stringref.h +// start catch_preprocessor.hpp + + +#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ +#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) + +#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ +// MSVC needs more evaluations +#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) +#else +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) +#endif + +#define CATCH_REC_END(...) +#define CATCH_REC_OUT + +#define CATCH_EMPTY() +#define CATCH_DEFER(id) id CATCH_EMPTY() + +#define CATCH_REC_GET_END2() 0, CATCH_REC_END +#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 +#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 +#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT +#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) +#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) + +#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) + +#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) + +// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, +// and passes userdata as the first parameter to each invocation, +// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) +#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) +#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ +#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ +#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) +#else +// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) +#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) +#endif + +#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ +#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) + +#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper()) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) +#else +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) +#endif + +#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ + CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) + +#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) +#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) +#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) +#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) +#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) +#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) +#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) +#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) +#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) +#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) +#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) + +#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N + +#define INTERNAL_CATCH_TYPE_GEN\ + template struct TypeList {};\ + template\ + constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ + template class...> struct TemplateTypeList{};\ + template class...Cs>\ + constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ + template\ + struct append;\ + template\ + struct rewrap;\ + template class, typename...>\ + struct create;\ + template class, typename>\ + struct convert;\ + \ + template \ + struct append { using type = T; };\ + template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ + struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ + template< template class L1, typename...E1, typename...Rest>\ + struct append, TypeList, Rest...> { using type = L1; };\ + \ + template< template class Container, template class List, typename...elems>\ + struct rewrap, List> { using type = TypeList>; };\ + template< template class Container, template class List, class...Elems, typename...Elements>\ + struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ + \ + template