[
  {
    "path": ".appends/.github/labels.yml",
    "content": "# ----------------------------------------------------------------------------------------- #\n# These are the repository-specific labels that augment the Exercise-wide labels defined in #\n# https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml.     #\n# ----------------------------------------------------------------------------------------- #\n\n- name: \"good first issue\"\n  description: \"\"\n  color: \"fafafa\"\n\n- name: \"help wanted\"\n  description: \"\"\n  color: \"Ff7f00\"\n\n- name: \"issue: in progress\"\n  description: \"Issue that is already occupied by somebody (usually by assigned person).\"\n  color: \"7987f2\"\n\n- name: \"issue: meta\"\n  description: \"Meta-discussions.\"\n  color: \"d4c5f9\"\n\n- name: \"issue: new exercise\"\n  description: \"Request to add new exercise.\"\n  color: \"ff9682\"\n\n- name: \"issue: ready for dev\"\n  description: \"Issue is ready for development.\"\n  color: \"97e87d\"\n\n- name: \"issue: requires investigation\"\n  description: \"This issue requires further investigation from maintainers.\"\n  color: \"26b75e\"\n\n- name: \"issue: waiting response\"\n  description: \"Issue marked with this label requires additional information from the author.\"\n  color: \"005b93\"\n\n- name: \"meta:v3\"\n  description: \"Discussions related to exercism v3\"\n  color: \"006b75\"\n\n- name: \"pr: dont merge\"\n  description: \"Don't merge this PR for some reasons (e.g. tests are failing).\"\n  color: \"ea3c99\"\n\n- name: \"pr: not ready\"\n  description: \"\"\n  color: \"ff0000\"\n\n- name: \"pr: rebase required\"\n  description: \"PR marked with this label requires rebase on other branch (`master` by default).\"\n  color: \"eeeeee\"\n\n- name: \"pr: review needed\"\n  description: \"\"\n  color: \"268902\"\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "content": "# Code owners\n.github/CODEOWNERS      @exercism/maintainers-admin\n\n# Changes to `fetch-configlet` should be made in the `exercism/configlet` repo\nbin/fetch-configlet     @exercism/maintainers-admin\n\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\n\nupdates:\n\n  # Keep dependencies for GitHub Actions up-to-date\n  - package-ecosystem: 'github-actions'\n    directory: '/'\n    schedule:\n      interval: 'monthly'\n"
  },
  {
    "path": ".github/labels.yml",
    "content": "# --------------------------------------------------------------- #\n# This is an auto-generated file - Do not manually edit this file #\n# --------------------------------------------------------------- #\n\n# This file is automatically generated by concatenating two files:\n#\n# 1. The Exercism-wide labels: defined in https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml\n# 2. The repository-specific labels: defined in the `.appends/.github/labels.yml` file within this repository.\n#\n# If any of these two files change, a pull request is automatically created containing a re-generated version of this file.\n# Consequently, to change repository-specific labels you should update the `.appends/.github/labels.yml` file and _not_ this file.\n#\n# When the pull request has been merged, the GitHub labels will be automatically updated by the \"Sync labels\" workflow.\n# This typically takes 5-10 minutes.\n\n# --------------------------------------------------------------------- #\n# These are the Exercism-wide labels which are shared across all repos. #\n# --------------------------------------------------------------------- #\n\n# The following Exercism-wide labels are used to show \"tasks\" on the website, which will point users to things they can contribute to.\n\n# The `x:action/<value>` labels describe what sort of work the contributor will be engaged in when working on the issue\n- name: \"x:action/create\"\n  description: \"Work on something from scratch\"\n  color: \"ffffff\"\n\n- name: \"x:action/fix\"\n  description: \"Fix an issue\"\n  color: \"ffffff\"\n\n- name: \"x:action/improve\"\n  description: \"Improve existing functionality/content\"\n  color: \"ffffff\"\n\n- name: \"x:action/proofread\"\n  description: \"Proofread text\"\n  color: \"ffffff\"\n\n- name: \"x:action/sync\"\n  description: \"Sync content with its latest version\"\n  color: \"ffffff\"\n\n# The `x:knowledge/<value>` labels describe how much Exercism knowledge is required by the contributor\n- name: \"x:knowledge/none\"\n  description: \"No existing Exercism knowledge required\"\n  color: \"ffffff\"\n\n- name: \"x:knowledge/elementary\"\n  description: \"Little Exercism knowledge required\"\n  color: \"ffffff\"\n\n- name: \"x:knowledge/intermediate\"\n  description: \"Quite a bit of Exercism knowledge required\"\n  color: \"ffffff\"\n\n- name: \"x:knowledge/advanced\"\n  description: \"Comprehensive Exercism knowledge required\"\n  color: \"ffffff\"\n\n# The `x:module/<value>` labels indicate what part of Exercism the contributor will be working on\n- name: \"x:module/analyzer\"\n  description: \"Work on Analyzers\"\n  color: \"ffffff\"\n\n- name: \"x:module/concept\"\n  description: \"Work on Concepts\"\n  color: \"ffffff\"\n\n- name: \"x:module/concept-exercise\"\n  description: \"Work on Concept Exercises\"\n  color: \"ffffff\"\n\n- name: \"x:module/generator\"\n  description: \"Work on Exercise generators\"\n  color: \"ffffff\"\n\n- name: \"x:module/practice-exercise\"\n  description: \"Work on Practice Exercises\"\n  color: \"ffffff\"\n\n- name: \"x:module/representer\"\n  description: \"Work on Representers\"\n  color: \"ffffff\"\n\n- name: \"x:module/test-runner\"\n  description: \"Work on Test Runners\"\n  color: \"ffffff\"\n\n# The `x:rep/<value>` labels describe the amount of reputation to award\n#\n# For more information on reputation and how these labels should be used,\n# check out https://exercism.org/docs/using/product/reputation\n- name: \"x:rep/tiny\"\n  description: \"Tiny amount of reputation\"\n  color: \"ffffff\"\n\n- name: \"x:rep/small\"\n  description: \"Small amount of reputation\"\n  color: \"ffffff\"\n\n- name: \"x:rep/medium\"\n  description: \"Medium amount of reputation\"\n  color: \"ffffff\"\n\n- name: \"x:rep/large\"\n  description: \"Large amount of reputation\"\n  color: \"ffffff\"\n\n- name: \"x:rep/massive\"\n  description: \"Massive amount of reputation\"\n  color: \"ffffff\"\n\n# The `x:size/<value>` labels describe the expected amount of work for a contributor\n- name: \"x:size/tiny\"\n  description: \"Tiny amount of work\"\n  color: \"ffffff\"\n\n- name: \"x:size/small\"\n  description: \"Small amount of work\"\n  color: \"ffffff\"\n\n- name: \"x:size/medium\"\n  description: \"Medium amount of work\"\n  color: \"ffffff\"\n\n- name: \"x:size/large\"\n  description: \"Large amount of work\"\n  color: \"ffffff\"\n\n- name: \"x:size/massive\"\n  description: \"Massive amount of work\"\n  color: \"ffffff\"\n\n# The `x:status/<value>` label indicates if there is already someone working on the issue\n- name: \"x:status/claimed\"\n  description: \"Someone is working on this issue\"\n  color: \"ffffff\"\n\n# The `x:type/<value>` labels describe what type of work the contributor will be engaged in\n- name: \"x:type/ci\"\n  description: \"Work on Continuous Integration (e.g. GitHub Actions workflows)\"\n  color: \"ffffff\"\n\n- name: \"x:type/coding\"\n  description: \"Write code that is not student-facing content (e.g. test-runners, generators, but not exercises)\"\n  color: \"ffffff\"\n\n- name: \"x:type/content\"\n  description: \"Work on content (e.g. exercises, concepts)\"\n  color: \"ffffff\"\n\n- name: \"x:type/docker\"\n  description: \"Work on Dockerfiles\"\n  color: \"ffffff\"\n\n- name: \"x:type/docs\"\n  description: \"Work on Documentation\"\n  color: \"ffffff\"\n\n# This Exercism-wide label is added to all automatically created pull requests that help migrate/prepare a track for Exercism v3\n- name: \"v3-migration 🤖\"\n  description: \"Preparing for Exercism v3\"\n  color: \"e99695\"\n\n# This Exercism-wide label can be used to bulk-close issues in preparation for pausing community contributions\n- name: \"paused\"\n  description: \"Work paused until further notice\"\n  color: \"e4e669\"\n\n# ----------------------------------------------------------------------------------------- #\n# These are the repository-specific labels that augment the Exercise-wide labels defined in #\n# https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml.     #\n# ----------------------------------------------------------------------------------------- #\n\n- name: \"good first issue\"\n  description: \"\"\n  color: \"fafafa\"\n\n- name: \"help wanted\"\n  description: \"\"\n  color: \"Ff7f00\"\n\n- name: \"issue: in progress\"\n  description: \"Issue that is already occupied by somebody (usually by assigned person).\"\n  color: \"7987f2\"\n\n- name: \"issue: meta\"\n  description: \"Meta-discussions.\"\n  color: \"d4c5f9\"\n\n- name: \"issue: new exercise\"\n  description: \"Request to add new exercise.\"\n  color: \"ff9682\"\n\n- name: \"issue: ready for dev\"\n  description: \"Issue is ready for development.\"\n  color: \"97e87d\"\n\n- name: \"issue: requires investigation\"\n  description: \"This issue requires further investigation from maintainers.\"\n  color: \"26b75e\"\n\n- name: \"issue: waiting response\"\n  description: \"Issue marked with this label requires additional information from the author.\"\n  color: \"005b93\"\n\n- name: \"meta:v3\"\n  description: \"Discussions related to exercism v3\"\n  color: \"006b75\"\n\n- name: \"pr: dont merge\"\n  description: \"Don't merge this PR for some reasons (e.g. tests are failing).\"\n  color: \"ea3c99\"\n\n- name: \"pr: not ready\"\n  description: \"\"\n  color: \"ff0000\"\n\n- name: \"pr: rebase required\"\n  description: \"PR marked with this label requires rebase on other branch (`master` by default).\"\n  color: \"eeeeee\"\n\n- name: \"pr: review needed\"\n  description: \"\"\n  color: \"268902\"\n"
  },
  {
    "path": ".github/workflows/configlet.yml",
    "content": "name: Configlet\n\non:\n  pull_request:\n  push:\n    branches:\n      - main\n  workflow_dispatch:\n\npermissions:\n  contents: read\n\njobs:\n  configlet:\n    uses: exercism/github-actions/.github/workflows/configlet.yml@main\n"
  },
  {
    "path": ".github/workflows/no-important-files-changed.yml",
    "content": "name: No important files changed\n\non:\n  pull_request_target:\n    types: [opened]\n    branches: [main]\n    paths:\n      - \"exercises/concept/**\"\n      - \"exercises/practice/**\"\n      - \"!exercises/*/*/.approaches/**\"\n      - \"!exercises/*/*/.articles/**\"\n      - \"!exercises/*/*/.docs/**\"\n      - \"!exercises/*/*/.meta/**\"\n\npermissions:\n  pull-requests: write\n\njobs:\n  check:\n    uses: exercism/github-actions/.github/workflows/check-no-important-files-changed.yml@main\n    with:\n      repository: ${{ github.event.pull_request.head.repo.owner.login }}/${{ github.event.pull_request.head.repo.name }}\n      ref: ${{ github.head_ref }}\n"
  },
  {
    "path": ".github/workflows/pause-community-contributions.yml",
    "content": "name: Pause Community Contributions\n\non:\n  issues:\n    types:\n      - opened\n  pull_request_target:\n    types:\n      - opened\n    paths-ignore:\n      - 'exercises/*/*/.approaches/**'\n      - 'exercises/*/*/.articles/**'\n\npermissions:\n  issues: write\n  pull-requests: write\n\njobs:\n  pause:\n    if: github.repository_owner == 'exercism' # Stops this job from running on forks\n    uses: exercism/github-actions/.github/workflows/community-contributions.yml@main\n    with:\n      forum_category: kotlin\n    secrets:\n      github_membership_token: ${{ secrets.COMMUNITY_CONTRIBUTIONS_WORKFLOW_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/ping-cross-track-maintainers-team.yml",
    "content": "name: Ping cross-track maintainers team\n\non:\n  pull_request_target:\n    types:\n      - opened\n\npermissions:\n  pull-requests: write\n\njobs:\n  ping:\n    if: github.repository_owner == 'exercism' # Stops this job from running on forks\n    uses: exercism/github-actions/.github/workflows/ping-cross-track-maintainers-team.yml@main\n    secrets:\n      github_membership_token: ${{ secrets.COMMUNITY_CONTRIBUTIONS_WORKFLOW_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/run-configlet-sync.yml",
    "content": "name: Run Configlet Sync\n\non:\n  workflow_dispatch:\n  schedule:\n    - cron: '0 0 15 * *'\n\njobs:\n  call-gha-workflow:\n    uses: exercism/github-actions/.github/workflows/configlet-sync.yml@main\n"
  },
  {
    "path": ".github/workflows/sync-labels.yml",
    "content": "name: Tools\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - .github/labels.yml\n      - .github/workflows/sync-labels.yml\n  workflow_dispatch:\n  schedule:\n    - cron: 0 0 1 * * # First day of each month\n\npermissions:\n  issues: write\n\njobs:\n  sync-labels:\n    uses: exercism/github-actions/.github/workflows/labels.yml@main\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: Kotlin / Test\n\non:\n  push:\n    branches: [main]\n  pull_request:\n  workflow_dispatch:\n\njobs:\n  ci:\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683\n\n      - name: Run tests for all exercises\n        run: bin/journey-test.sh\n"
  },
  {
    "path": ".gitignore",
    "content": "*.swp\n.DS_Store\nbin/configlet\nbin/configlet.exe\nbin/jq*\nCHECKLIST\nbuild\n.gradle\n.idea\n*.iml\nout/\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Code of Conduct\n\n## Introduction\n\nExercism is a platform centered around empathetic conversation.\nWe have a low tolerance for communication that makes anyone feel unwelcome, unsupported, insulted or discriminated against.\n\n## Seen or experienced something uncomfortable?\n\nIf you see or experience abuse, harassment, discrimination, or feel unsafe or upset, please email [abuse@exercism.org](mailto:abuse@exercism.org?subject=%5BCoC%5D) and include \\[CoC\\] in the subject line.\nWe will follow up with you as a priority.\n\n## Enforcement\n\nWe actively monitor for Code of Conduct (CoC) violations and take any reports of violations extremely seriously.\nWe have banned contributors, mentors and users due to violations.\n\nAfter we receive a report of a CoC violation, we view that person's conversation history on Exercism and related communication channels and attempt to understand whether someone has deliberately broken the CoC, or accidentally crossed a line.\nWe generally reach out to the person who has been reported to discuss any concerns we have and warn them that repeated violations will result in a ban.\nSometimes we decide that no violation has occurred and that no action is required and sometimes we will also ban people on a first offense.\nWe strive to be fair, but will err on the side of protecting the culture of our community.\n\nExercism's leadership reserve the right to take whatever action they feel appropriate with regards to CoC violations.\n\n## The simple version\n\n- Be empathetic\n- Be welcoming\n- Be kind\n- Be honest\n- Be supportive\n- Be polite\n\n## The details\n\nExercism should be a safe place for everybody regardless of\n\n- Gender, gender identity or gender expression\n- Sexual orientation\n- Disability\n- Physical appearance (including but not limited to body size)\n- Race\n- Age\n- Religion\n- Anything else you can think of\n\nAs someone who is part of this community, you agree that:\n\n- We are collectively and individually committed to safety and inclusivity\n- We have zero tolerance for abuse, harassment, or discrimination\n- We respect people’s boundaries and identities\n- We refrain from using language that can be considered offensive or oppressive (systemically or otherwise), eg. sexist, racist, homophobic, transphobic, ableist, classist, etc.\n  - this includes (but is not limited to) various slurs.\n- We avoid using offensive topics as a form of humor\n\nWe actively work towards:\n\n- Being a safe community\n- Cultivating a network of support & encouragement for each other\n- Encouraging responsible and varied forms of expression\n\nWe condemn:\n\n- Stalking, doxxing, or publishing private information\n- Violence, threats of violence or violent language\n- Anything that compromises people’s safety\n- Conduct or speech which might be considered sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory or offensive in nature\n- The use of unwelcome, suggestive, derogatory or inappropriate nicknames or terms\n- Disrespect towards others (jokes, innuendo, dismissive attitudes) and towards differences of opinion\n- Intimidation or harassment (online or in-person).\n  Please read the [Citizen Code of Conduct](https://github.com/stumpsyn/policies/blob/master/citizen_code_of_conduct.md) for how we interpret harassment\n- Inappropriate attention or contact\n- Not understanding the differences between constructive criticism and disparagement\n\nThese things are NOT OK.\n\nBe aware of how your actions affect others.\nIf it makes someone uncomfortable, stop.\n\nIf you say something that is found offensive, and you are called out on it, try to:\n\n- Listen without interruption\n- Believe what the person is saying & do not attempt to disqualify what they have to say\n- Ask for tips / help with avoiding making the offense in the future\n- Apologize and ask forgiveness\n\n## History\n\nThis policy was initially adopted from the Front-end London Slack community and has been modified since.\nA version history can be seen on [GitHub](https://github.com/exercism/website-copy/edit/main/pages/code_of_conduct.md).\n\n_This policy is a \"living\" document, and subject to refinement and expansion in the future.\nThis policy applies to the Exercism website, the Exercism GitHub organization, any other Exercism-related communication channels (e.g. Discord, Forum, Twitter, email) and any other Exercism entity or event._\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 Exercism\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Exercism Kotlin Track\n\n[![Build Status](https://travis-ci.org/exercism/kotlin.svg?branch=master)](https://travis-ci.org/exercism/kotlin)\n\nSource for Exercism Exercises in Kotlin.\n\n## Contributing Guide\n\nFor general information about how to contribute to Exercism, please refer to the [contributing guide](https://exercism.org/docs/building).\n\n## Table of Contents\n\n* [Overview](#overview)\n* [Contributing With Minimal Setup](#contributing-with-minimal-setup)\n* [Getting Familiar With the Codebase](#getting-familiar-with-the-codebase)\n  * [The `exercises` Module](#the-exercises-module)\n  * [The Problem Submodules](#the-problem-submodules)\n* [Advanced: Complete Local Setup](#advanced-complete-local-setup)\n  * [Tip: `gradle clean` before `exercism fetch`](#tip-gradle-clean-before-exercism-fetch)\n\n\n## Overview\n\nThis guide covers contributing to the Kotlin track.  If you are new, this guide is for you.\n\nIf, at any point, you're having any trouble, pop in the [Building Exercism](https://forum.exercism.org/c/exercism/building-exercism/125) category of the [Exercism forum](https://forum.exercism.org/) for help.\n\n## Contributing With Minimal Setup\n\nFirst things first: by contributing to Exercism, you are making this learning tool that much better and improving our industry as a whole... thank you!!!\n\nTo submit a fix for an existing exercise or port an exercise to Kotlin with the least amount of setup:\n\n1. **Ensure you have the basic Java tooling installed:**  JDK 1.8+, an editor and Gradle 2.x.\n\n   (see [exercism.io: Installing Kotlin](https://exercism.org/docs/tracks/kotlin/installation))\n-  **Setup a branch on a fork of [exercism/kotlin](https://github.com/exercism/kotlin) on your computer.**\n\nNext steps:\n   * \"fork\" a repository on GitHub;\n   - install `git`;\n   - \"clone\" a copy of your fork;\n   - configure an \"upstream remote\" (in this case, `exercism/kotlin`);\n   - create a branch to house your work\n-  **Write the codes.**  Do your work on that branch you just created.\n\n   The [Getting Familiar With the Codebase](#getting-familiar-with-the-codebase) section, below, is an orientation.\n-  **Commit, push and create a pull request.**\n\n   Something like:\n   ```\n   $ git add .\n   $ git commit -m \"(An intention-revealing commit message)\"\n   $ git push\n   ```\n\n   It is advised you write meaningful commit messages. [Chris Beams wrote about \"How to Write a Git Commit Message\"](https://chris.beams.io/posts/git-commit/).\n\n-  **Verify that your work passes all tests.**  When you create a pull request (PR), GitHub triggers a build on Travis CI.  Your PR will not be merged unless those tests pass.\n\n## Getting Familiar With the Codebase\n\nThere are two objectives to the design of this build:\n\n1. when a problem is built from within the `exercism/kotlin` repo (i.e. when you, the contributor, are developing the exercise), the tests run against the reference solution;\n2. when a problem is built outside the `exercism/kotlin` repo (when a participant is solving the exercise), the tests run against the \"main\" code.\n\nThis repo is a multi-project gradle build.\n\n### The `exercises` Module\n\nThis is the top-level module, contained in the `exercises` directory.  It is a container for the problem sub-modules.\n\n  * its `build.gradle` points the \"main\" sourceset to the reference solution.\n  * its `settings.gradle` names each of the subprojects, one for each problem in the set.\n\n### The Problem Submodules\n\nThe `exercises` subdirectory contains all of the problem submodules.\nEach problem/submodule is a subdirectory of the same name as its slug.\n\n  * its `build.gradle.kts` names dependencies required to work that problem.\n\nEach problem/submodule has three source sets:\n\n* `src/test/kotlin/` — a test suite defining the edges of the problem\n* `.meta/src/reference/kotlin/` — a reference solution that passes all the tests\n* `src/main/kotlin/` — starter source files, if required/desired *(this directory usually only has a `.keep` file in it)*.\n\nTo run the tests for a specific exercise, run the `test` Gradle task from the exercises\ndirectory. For example:\n\n```bash\ncd exercises\nhttps://github.com/exercism/v3/blob/main/gradlew bob:test\n\n```\n\nSteps for modifying an exercise:\n1. Change the test(s).\n2. Watch the changes fail.\n3. Update the reference solution to make the test(s) pass.\n\n----\n\n## Advanced: Complete Local Setup\n\nIf you are going to make significant contribution(s) to the track, you might find it handy to have a complete local install of exercism on your computer.  This way, you can run the full suite of tests without having to create/update a PR.\n\nThe easiest way to achieve this is simply use the `bin/journey-test.sh` script.  However, you may want to perform other tests, depending on what you are doing.  You can do so by duplicating the setup performed by the `bin/journey-test.sh` script.\n\n### Tip: `gradle clean` before `exercism fetch`\n\nIf you `exercism fetch` after doing a build, the CLI will fail with the following error message:\n\n```\n$ exercism fetch kotlin bob\n2015/09/06 15:03:21 an internal server error was received.\nPlease file a bug report with the contents of 'exercism debug' at: https://github.com/exercism/exercism.io/issues\n```\n\nand if you review the logs of your x-api, you'll find:\n\n```\n127.0.0.1 - - [06/Sep/2015:15:20:56 -0700] \"GET /v2/exercises/kotlin/bob HTTP/1.1\" 500 514949 0.2138\n2015-09-06 15:21:01 - JSON::GeneratorError - source sequence is illegal/malformed utf-8:\n```\n\nThis is because some files generated by the build can't be served from the x-api.  This is by design: the CLI does not serve binaries.  To fix this, simply make sure you do a clean in your `exercism/kotlin` repo before you fetch:\n\n```\ncd ~/workspace/exercism/kotlin/exercises\ngradle clean\ncd ~/workspace/exercism/exercises\nexercism fetch kotlin bob\n```\n"
  },
  {
    "path": "_template/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "_template/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "_template/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "_template/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "_template/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "_template/src/example/kotlin/.keep",
    "content": ""
  },
  {
    "path": "_template/src/main/kotlin/.keep",
    "content": ""
  },
  {
    "path": "_template/src/test/kotlin/.keep",
    "content": ""
  },
  {
    "path": "bin/README.md",
    "content": "# Cross-track consistency\n\nMany of these scripts are shared between the Java and Kotlin tracks. If you make an update to a script in one of these tracks, please also update the same script in the other track if appropriate. Thank you!\n"
  },
  {
    "path": "bin/build-jq.sh",
    "content": "#!/usr/bin/env bash\nset -ex\n\npushd bin\ncurl --location https://github.com/stedolan/jq/releases/download/jq-1.5/jq-1.5.tar.gz >jq-1.5.tar.gz\ntar xvf jq-1.5.tar.gz\ncd jq-1.5\n./configure --disable-maintainer-mode && make\nmv jq ..\npopd\n\n"
  },
  {
    "path": "bin/fetch-configlet",
    "content": "#!/usr/bin/env bash\n\n# This file is a copy of the\n# https://github.com/exercism/configlet/blob/main/scripts/fetch-configlet file.\n# Please submit bugfixes/improvements to the above file to ensure that all tracks benefit from the changes.\n\nset -eo pipefail\n\ncurlopts=(\n  --silent\n  --show-error\n  --fail\n  --location\n  --retry 3\n)\n\nif [[ -n \"${GITHUB_TOKEN}\" ]]; then\n  curlopts+=(--header \"authorization: Bearer ${GITHUB_TOKEN}\")\nfi\n\nget_download_url() {\n  local os=\"$1\"\n  local ext=\"$2\"\n  local latest='https://api.github.com/repos/exercism/configlet/releases/latest'\n  local arch\n  case \"$(uname -m)\" in\n    aarch64|arm64) arch='arm64'  ;;\n    x86_64)        arch='x86-64' ;;\n    *686*)         arch='i386'   ;;\n    *386*)         arch='i386'   ;;\n    *)             arch='x86-64' ;;\n  esac\n  local suffix=\"${os}_${arch}.${ext}\"\n  curl \"${curlopts[@]}\" --header 'Accept: application/vnd.github.v3+json' \"${latest}\" |\n    grep \"\\\"browser_download_url\\\": \\\".*/download/.*/configlet.*${suffix}\\\"$\" |\n    cut -d'\"' -f4\n}\n\nmain() {\n  local output_dir\n  if [[ -d ./bin ]]; then\n    output_dir=\"./bin\"\n  elif [[ $PWD == */bin ]]; then\n    output_dir=\"$PWD\"\n  else\n    echo \"Error: no ./bin directory found. This script should be ran from a repo root.\" >&2\n    return 1\n  fi\n\n  local os\n  case \"$(uname -s)\" in\n    Darwin*)   os='macos'   ;;\n    Linux*)    os='linux'   ;;\n    Windows*)  os='windows' ;;\n    MINGW*)    os='windows' ;;\n    MSYS_NT-*) os='windows' ;;\n    *)         os='linux'   ;;\n  esac\n\n  local ext\n  case \"${os}\" in\n    windows) ext='zip'    ;;\n    *)       ext='tar.gz' ;;\n  esac\n\n  echo \"Fetching configlet...\" >&2\n  local download_url\n  download_url=\"$(get_download_url \"${os}\" \"${ext}\")\"\n  local output_path=\"${output_dir}/latest-configlet.${ext}\"\n  curl \"${curlopts[@]}\" --output \"${output_path}\" \"${download_url}\"\n\n  case \"${ext}\" in\n    zip) unzip \"${output_path}\" -d \"${output_dir}\"   ;;\n    *)   tar xzf \"${output_path}\" -C \"${output_dir}\" ;;\n  esac\n\n  rm -f \"${output_path}\"\n\n  local executable_ext\n  case \"${os}\" in\n    windows) executable_ext='.exe' ;;\n    *)       executable_ext=''     ;;\n  esac\n\n  local configlet_path=\"${output_dir}/configlet${executable_ext}\"\n  local configlet_version\n  configlet_version=\"$(${configlet_path} --version)\"\n  echo \"Downloaded configlet ${configlet_version} to ${configlet_path}\"\n}\n\nmain\n"
  },
  {
    "path": "bin/journey-test.sh",
    "content": "#!/usr/bin/env bash\n\nTRACK=kotlin\nTRACK_REPO=\"$TRACK\"\nEXERCISES_TO_SOLVE=$@\n\non_exit() {\n    echo \">>> on_exit()\"\n    cd $EXECPATH\n    echo \"<<< on_exit()\"\n}\n\nassert_installed() {\n    local binary=$1\n    echo \">>> assert_installed(binary=\\\"${binary}\\\")\"\n    \n    if [[ \"`which $binary`\" == \"\" ]]; then\n        echo \"${binary} not found; it is required to perform this test.\"\n        echo -e \"Have you completed the setup instructions at https://github.com/exercism/${TRACK_REPO} ?\\n\"\n        echo \"PATH=${PATH}\"\n        echo \"aborting.\"\n        exit 1\n    fi\n    echo \"<<< assert_installed()\"\n}\n\nclean() {\n    local build_dir=\"$1\"\n    echo \">>> clean(build_dir=\\\"${build_dir}\\\")\"\n    \n    # empty, absolute path, or parent reference are considered dangerous to rm -rf against.\n    if [[ \"${build_dir}\" == \"\" || ${build_dir} =~ ^/ || ${build_dir} =~ \\.\\. ]] ; then\n        echo \"Value for build_dir looks dangerous.  Aborting.\"\n        exit 1\n    fi\n    \n    local build_path=$( pwd )/${build_dir}\n    if [[ -d \"${build_path}\" ]] ; then\n        echo \"Cleaning journey script build output directory (${build_path}).\"\n        rm -rf \"${build_path}\"\n    fi\n    cd exercises\n    \"$EXECPATH\"/gradlew clean\n    cd ..\n    echo \"<<< clean()\"\n}\n\nsolve_exercise() {\n    local exercise=\"$1\"\n    local exercise_type=\"$2\"\n\n    echo -e \"\\n\\n\"\n    echo \"==================================================\"\n    echo \"Solving ${exercise}\"\n    echo \"==================================================\"\n\n    mkdir -p ${exercism_exercises_dir}/${TRACK}\n    cp -R -H ${track_root}/exercises/${exercise_type}/${exercise} ${exercism_exercises_dir}/${TRACK}/${exercise}\n    cp -R -H ${track_root}/exercises/${exercise_type}/${exercise}/.meta/src/reference/${TRACK}/* ${exercism_exercises_dir}/${TRACK}/${exercise}/src/main/${TRACK}/\n    \n    pushd ${exercism_exercises_dir}/${TRACK}/${exercise}\n    # Check that tests compile before we strip @Ignore annotations\n    \"$EXECPATH\"/gradlew compileTestJava\n    # Ensure we run all the tests (as delivered, all but the first is @Ignore'd)\n    for testfile in `find src/test/kotlin -name \"*Test.kt\"`; do\n        # Strip @Ignore annotations to ensure we run the tests (as delivered, all but the first is @Ignore'd).\n        # Note that unit-test.sh also strips @Ignore annotations via the Gradle task copyTestsFilteringIgnores.\n        # The stripping implementations here and in copyTestsFilteringIgnores should be kept consistent.\n        sed 's/@Ignore\\(\\(.*\\)\\)\\{0,1\\}//' ${testfile} > \"${tempfile}\" && mv \"${tempfile}\" \"${testfile}\"\n    done\n    \"$EXECPATH\"/gradlew test\n    echo \"exit code: $?\"\n    popd\n}\n\nsolve_all_exercises() {\n    local exercism_exercises_dir=\"$1\"\n    echo \">>> solve_all_exercises(exercism_exercises_dir=\\\"${exercism_exercises_dir}\\\")\"\n    \n    local track_root=$( pwd )\n    local concept_exercises=`jq -r '.exercises.concept[].slug' config.json | sort | xargs`\n    local practice_exercises=`jq -r '.exercises.practice[].slug' config.json | sort | xargs`\n    local total_exercises=`jq '.exercises.concept + .exercises.practice | length' config.json`\n    local current_exercise_number=1\n    local tempfile=\"${TMPDIR:-/tmp}/journey-test.sh-unignore_all_tests.txt\"\n\n    mkdir -p ${exercism_exercises_dir}\n    pushd ${exercism_exercises_dir}\n\n    for exercise in $concept_exercises; do\n        echo -e \"\\n\\n\"\n        echo \"==================================================\"\n        echo \"${current_exercise_number} of ${total_exercises} -- ${exercise}\"\n        echo \"==================================================\"\n        \n        solve_exercise \"${exercise}\" \"concept\"\n        \n        current_exercise_number=$((current_exercise_number + 1))\n    done\n\n    for exercise in $practice_exercises; do\n        echo -e \"\\n\\n\"\n        echo \"==================================================\"\n        echo \"${current_exercise_number} of ${total_exercises} -- ${exercise}\"\n        echo \"==================================================\"\n        \n        solve_exercise \"${exercise}\" \"practice\"\n        \n        current_exercise_number=$((current_exercise_number + 1))\n    done\n    popd\n}\n\nsolve_single_exercise() {\n    local exercism_exercises_dir=\"$1\"\n    local exercise_to_solve=\"$2\"\n    local exercise_type=\"$3\"\n    echo \">>> solve_single_exercises(exercism_exercises_dir=\\\"${exercism_exercises_dir}\\\", exercise_to_solve=\\\"$exercise_to_solve\\\")\"\n    \n    local track_root=$( pwd )\n    local tempfile=\"${TMPDIR:-/tmp}/journey-test.sh-unignore_all_tests.txt\"\n    \n    mkdir -p ${exercism_exercises_dir}\n    pushd ${exercism_exercises_dir}\n    \n    solve_exercise \"${exercise_to_solve}\" \"${exercise_type}\"\n    \n    popd\n}\n\nmain() {\n    # all functions assume current working directory is repository root.\n    cd \"${SCRIPTPATH}/..\"\n    \n    local track_root=$( pwd )\n    local build_dir=\"build\"\n    local build_path=\"${track_root}/${build_dir}\"\n    \n    local exercism_home=\"${build_path}/exercism\"\n    \n    # fail fast if required binaries are not installed.\n    assert_installed \"jq\"\n    \n    clean \"${build_dir}\"\n    \n    if [[ $EXERCISES_TO_SOLVE == \"\" ]]; then\n        solve_all_exercises \"${exercism_home}\"\n    else\n        for exercise in $EXERCISES_TO_SOLVE; do\n            if [ -d \"${exercism_home}/exercises/concept/${exercise}\" ]; then\n                solve_single_exercise \"${exercism_home}\" \"${exercise}\" \"concept\"\n            else\n                solve_single_exercise \"${exercism_home}\" \"${exercise}\" \"practice\"\n            fi\n        done\n    fi\n}\n\n##########################################################################\n# Execution begins here...\n\n# If any command fails, fail the script.\nset -exo pipefail\nSCRIPTPATH=$( pushd `dirname $0` > /dev/null && pwd && popd > /dev/null )\nEXECPATH=$( pwd )\n# Make output easier to read in CI\nTERM=dumb\n\ntrap on_exit EXIT\nmain\n\n"
  },
  {
    "path": "bin/run-journey-test-from-ci.sh",
    "content": "#!/bin/bash\n\ncontains_setup_file() {\n    local files=$1\n    for file in $files; do\n        if [[ $file == *.gradle || $file == *.gradle.kts || $file == *.sh || $file == config.json ]]; then\n            return 0\n        fi\n    done\n    return 1\n}\n\ncontains_exercise() {\n    local files=$1\n    for file in $files; do\n        if [[ $file == exercises* ]]; then\n            return 0\n        fi\n    done\n    return 1\n}\n\nrun_journey_test_with_modified_exercises() {\n    local modded_files=$1\n    local last_modded_exercise=\"\"\n    local modded_exercises=\"\"\n    \n    for file in $modded_files; do\n        if [[ $file == exercises* ]] && [[ $file != exercises/settings.gradle ]] && [[ $file != exercises/build.gradle.kts ]]; then\n            local modded_exercise=${file#exercises/}\n            modded_exercise=${modded_exercise%%/*}\n            if [[ $last_modded_exercise != $modded_exercise ]]; then\n                modded_exercises=$modded_exercises$modded_exercise$'\\n'\n            fi\n            last_modded_exercise=$modded_exercise\n        fi\n    done\n    \n    echo \"Running journey test with modified exercise(s): ${modded_exercises}\"\n    bin/journey-test.sh $modded_exercises\n}\n\nrun_journey_test_with_all_exercises() {\n    echo \"Running journey test with all exercises\"\n    bin/journey-test.sh\n}\n\nmain() {\n    bin/build-jq.sh\n    \n    local pr_files_json=`curl -s https://api.github.com/repos/exercism/kotlin/pulls/${TRAVIS_PULL_REQUEST}/files`\n    \n    echo \"Pull request number: ${TRAVIS_PULL_REQUEST}\"\n    echo \"Changes in pr json: ${pr_files_json}\"\n    \n    # if jq fails to get the required data, then that means TRAVIS_PULL_REQUEST was not set (not run in travis-ci),\n    # or was false (not a pull request), or the api limit was reached, or some other error occurred.\n    # In that case, we should fall back with testing every exercise\n    local pr_files_json_type=`echo $pr_files_json | bin/jq -r 'type'`\n    if [[ $pr_files_json_type != \"array\" ]]; then\n        echo \"Didn't get pr changes from travis\"\n        run_journey_test_with_all_exercises\n        return\n    fi\n    \n    local modded_files=`echo $pr_files_json | bin/jq -r '.[].filename'`\n    \n    # If the changed files contain a .sh file or .gradle.kts file or config.json then we should run all the exercises\n    if contains_setup_file \"${modded_files}\"; then\n        echo \"Pr changes contain setup file(s): ${modded_files}\"\n        run_journey_test_with_all_exercises\n        return\n    fi\n    \n    if contains_exercise \"${modded_files}\"; then\n        echo \"Pr changes contain modified exercise file(s)\"\n        run_journey_test_with_modified_exercises \"${modded_files}\"\n    fi\n}\n\ntrap 'exit 1' ERR\nmain\n\n"
  },
  {
    "path": "bin/unit-tests.sh",
    "content": "#!/usr/bin/env bash\nset -e\n./gradlew --version\n\n# Clean up any left-over files from a previous invocation, to avoid configlet\n# erroring when it finds an unexpected directory inside exercises.\nrm -rf ./exercises/build\n\necho \"\"\necho \">>> Running configlet...\"\nbin/fetch-configlet\nbin/configlet lint\n\npushd exercises\necho \"\"\necho \">>> Running tests...\"\nTERM=dumb ../gradlew check compileStarterSourceKotlin --continue\npopd\n\n"
  },
  {
    "path": "concepts/basics/.meta/config.json",
    "content": "{\n  \"blurb\": \"TODO: add blurb for basics concept\",\n  \"authors\": [\n    \"dector\"\n  ],\n  \"contributors\": []\n}\n"
  },
  {
    "path": "concepts/basics/about.md",
    "content": "# About Basics\n\nKotlin is a statically typed language, designed to be fully interoperable with Java.\n\nDistinguishing it from Java, Kotlin:\n\n- has a cleaner, more concise syntax;\n- incorporates many features of functional languages;\n- has extensive support for nullable values.\n\n## Variables\n\nBecause Kotlin is statically typed, it is necessary to _know_ the type of each value at compile time.\n\nHowever, Kotlin's [type inference][inference] is very powerful, so _specifying_ the type is often optional.\n\nThere are two ways to declare a variable.\n\n1. `val` creates an immutable variable, and trying to change it is a compile-time error.\n\n```kotlin\nval x = 42  // => 42\nx = 43      // => 'val' cannot be reasssigned\n```\n\n2. `var` creates a mutable variable.\n\n```Kotlin\nvar x = 42  // => 42\nx = 43      // => 43\n```\n\nBecause immutable variables eliminate a common class of bugs, use of `val` is encouraged whenever possible.\n\nAlso, even a `var` cannot change type:\n\n```kotlin\nvar x = 42\nx = \"foobar\" // => Type mismatch: inferred type is String but Int was expected\n```\n\nTo reduce visual distraction, explicit types will mostly be omitted from this syllabus.\nNevertheless, it is recommended to specify types at least for:\n\n- public APIs\n- function signatures\n- where it needs documentation\n\nSome companies and organisations will require strict type safety and disallow type inference, whilst others restrict it to \"simple\" types, or embrace type inference fully.\n\n```kotlin\nval x: Int = 42  // => 42\n```\n\nIn general, the names of variables and functions should be in `camelCase`, not `snake_case`\n\n## Functions\n\nDeclare a function with the `fun` keyword.\nUnlike Java, functions are not required to be part of a class.\n\n```Kotlin\nfun hello(): String {\n    return \"Hello, World!\"\n}\n\nfun add(x: Int, y: Int): Int {\n    return x + y\n}\n```\n\nSome points to note:\n\n- Parentheses `()` are needed after the function name, even if the function takes no arguments.\n- Function arguments need to specify the type: there is no type inference (in contrast to variables).\n- The body of the function is enclosed in braces `{ }` (though see below).\n- The `return` keyword is required, if returning a value.\n- Semicolons `;` at the end of lines are optional, and usually omitted.\n- Arithmetic operators `+`, `-`, `*`, `/` are similar to most mainstream languages.\n\nHowever, for these very simple, \"single-expression\" functions, there is an abbreviated syntax:\n\n```Kotlin\n// return type is usually omitted for single-expression functions\nfun add(x: Int, y: Int) = x + y  \n```\nFunctions can have parameters with default values. \nThese values will be used if they are omitted where the function is invoked:\n\n```kotlin\nfun ping(host: String = \"localhost\") {\n    println(\"PING --> $host\")\n}\n\nping(\"exercism.io\")  // PING --> exercism.io\nping()               // PING --> localhost\n```\n\nFunctions within Exercism will usually return a value (because of the way the test runner is structured).\nTo use Kotlin more widely, it may be useful to know that a function which returns no value can omit the return type and the return keyword.\n\nIt is then said to have a `Unit` return type: equivalent to `void` in Java and several other languages.\n\n## Comments\n\nSingle-line comments start with `//`, and the rest of the line is then ignored.\n\nMulti-line comments start with `/*` and end with `*/`\n\n```Kotlin\nfun hello(): String {\n    /*\n     * Failing to run this program on a new installation \n     * is considered bad luck\n    */\n    return \"Hello, World!\" // the compiler pixies are now happy\n}\n```\n\nThis is the same as Java.\n\n~~~~exercism/note\nBecause of the importance of Java interop, many Kotlin learners are at least somewhat familiar with Java.\n\nWe will try to point out similarities and differences between the languages throughout the syllabus.\n\n_Please ignore this if you are a Kotlin-first learner!_\n~~~~\n\n\n[inference]: https://en.wikipedia.org/wiki/Type_inference\n"
  },
  {
    "path": "concepts/basics/introduction.md",
    "content": "# Introduction\n\nKotlin is a **statically typed** programming language developed by JetBrains. This means that the type of variables is defined at compile-time.\n\n## Variables\n\nSimilarly to other statically-typed programming languages, the type of each variable should be defined at compile time. You can avoid explicit type declarations where they can be inferred by the compiler from their context.\n\nKotlin has immutable (`val`) and mutable (`var`) variables. The value of an immutable variable can't be changed after it's initial value is assigned. Most of the time you will use this type of variable.\n\n```kotlin\nval robotName = \"HAL-9000\"\nuserId = \"T-1000\"  // This will not compile\n```\n\nA mutable variable's value can be changed one or more times:\n\n```kotlin\nvar index = 12\nprint(index)  // 12\n\nindex = 100\nprint(index)  // 100\n```\n\nSemicolons in Kotlin are optional, except for a few special cases that will be covered later.\n\n## Functions\n\nFunctions in Kotlin are defined with the `fun` keyword and are _first-class citizens_ (not related to OOP). It means that you can declare (so-called `top-level functions`) them right in files (e.g. in Java you can define methods only in classes, not in files):\n\n```kotlin\n// This is content of the Hello.kt file\n\nfun hello() {}\n```\n\nFunctions can receive arguments. Each argument has a name and a type. Unlike variables, the type of arguments can't be inferred. Functions can have zero or more arguments:\n\n```kotlin\nfun hello() {}\n\nfun hello(name: String) {}\n\nfun hello(name: String, age: Int) {}\n```\n\nKotlin functions might or might not return a value:\n\n```kotlin\nfun min(a: Int, b: Int): Int\n\nfun countBonuses(user: User): Bonuses\n\nfun run() {}\n```\n\nTo return a value from a function, the `return` keyword is used:\n\n```kotlin\nfun getName(): String {\n    return \"Alice\"\n}\n```\n\nFunctions can have parameters with default values. These values will be used if they are omitted where function is invoked:\n\n```kotlin\nfun ping(host: String = \"localhost\") {\n    println(\"PING --> $host\")\n}\n\nping(\"exercism.io\")  // PING --> exercism.io\nping()               // PING --> localhost\n```\n\n## Comments\n\nUse `//` to define single-line comment:\n\n```kotlin\nfoo() // Everything after `//` will be ignored by compiler\n\n// I will be ignored too\n```\n\nor `/*` and `*/` to define multi-line comments:\n\n```kotlin\n/*\n   This this an example\n   for a multiline comment\n*/\n```\n"
  },
  {
    "path": "concepts/basics/links.json",
    "content": "[]\n"
  },
  {
    "path": "concepts/bitwise-operations/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"colinleach\"\n  ],\n  \"contributors\": [],\n  \"blurb\": \"Kotlin provides a set of bitwise operations that allow you to manipulate the individual bits of integers.\"\n}\n"
  },
  {
    "path": "concepts/bitwise-operations/about.md",
    "content": "# About Bits\n\nBinary digits ultimately map directly to the transistors in your CPU or RAM, and whether each is \"on\" or \"off\".\n\nLow-level manipulation, informally called \"bit-twiddling\", is particularly important in system languages.\n\nHigher-level languages like Kotlin usually abstract away most of this detail.\nHowever, a basic range of bit-level operations [is available][ref-bitwise].\n\n~~~~exercism/note\nTo see human-readable binary output, nearly all the examples below need to be wrapped in an [`Integer.toBinaryString()`][web-binstring] function, or converted with `toString(radix = 2)`.\n \nThis is visually distracting, so most occurrences of this function have been edited out, and the results are represented with `0b` notation.\n\n[web-binstring]: https://www.baeldung.com/kotlin/int-binary-representation\n~~~~\n\n## Bit-shift operations\n\n`Int` or `Long` types, both signed and unsigned, can be represented as a String of 1's and 0's, and manipulated as a sequence of bits.\n\nPerhaps surprisingly, `Byte` or `Short` types are not compatible with most bitwise operations in Kotlin.\nAll the examples below use 32-bit integers (`Int` or `UInt`).\n\n```kotlin\nval ns = 0b111  // 7 decimal\nInteger.toBinaryString(ns)  // => \"111\"\n```\n\nBit-shifts move everything to the left or right by a specified number of positions.\nSome bits drop off one end, and the other end is padded with zeros or ones.\n\n- Left shift with `shl`: zero-padding.\n- Right shift with `shr` or `ushr`: zero padding for positive numbers (see later section for negative numbers).\n\n```kotlin\nval ns = 0b111  // 7 decimal\nns shl 1  // => 0b1110, decimal 14\nns shr 1  // => 0b11, decimal 3\nns ushr 1  // => 0b11\n\nval nu: UInt = 0b111u  // 7 unsigned\nnu shr 1  //  => 0b11\n```\n\nEach left-shift doubles the value, and each right-shift halves it (subject to truncation).\nThis is more obvious in decimal representation:\n\n```kotlin\n3 shl 2  // => 12\n24 shr 3 // => 3\n```\n\nSuch bit-shifting is much faster than \"proper\" arithmetic, making the technique very popular in low-level coding.\n\n### Bit-shifting negative integers\n\nWith _negative integers_, we need to be a bit more careful.\n\nNegative values are stored in [two's complement][wiki-2complement] form, which means that the left-most bit is 1.\nNo problem for a left-shift, but when right-shifting how do we pad the left-most bits?\n\n```kotlin\nval ns = -0b111  // => 0b11111111111111111111111111111001\n\n// shift left: simple\nns shl 1  // => 0b11111111111111111111111111110010, decimal -14\n\n// shift right: preserves sign bit\nns shr 1  // => 0b11111111111111111111111111111100, decimal -4\n\n// unsigned shift right: left-pads with zeros\nns ushr 1 // => 0b01111111111111111111111111111100, decimal 2147483644\n```\n\nThe [`shr`][ref-shr] operator performs [arithmetic shift][wiki-arithmetic], preserving the sign bit.\n\nThe [`ushr`][ref-ushr] operator performs [logical shift][wiki-logical], padding with zeros as if the number was unsigned.\n\n## Bitwise logic\n\nWe saw in the [Booleans Concept][concept-booleans] that the operators `&&` (and), `||` (or) and `!` (not) are used with boolean values.\n\nThere are equivalent operators `and`, `or`, `xor` ([exclusive-or][wiki-xor]) to compare the bits in two integers, and an `inv` (inversion) function to flip all the bits.\n\n```kotlin\n0b1011 and 0b0010 //  bit is 1 in both numbers\n// => 0b0010\n\n0b1011 or 0b0010 // bit is 1 in at least one number\n// => 0b1011\n\n0b1011 xor 0b0010 // bit is 1 in exactly one number, not both\n// => 0b1001\n\n0b1011.inv() // flip all bits (in a 32-bit signed Int)\n// => 0b11111111111111111111111111110100\n```\n\n\n[ref-bitwise]: https://kotlinlang.org/docs/numbers.html#bitwise-operations\n[wiki-xor]: https://en.wikipedia.org/wiki/Exclusive_or\n[wiki-2complement]: https://en.wikipedia.org/wiki/Two%27s_complement\n[wiki-arithmetic]: https://en.wikipedia.org/wiki/Arithmetic_shift\n[wiki-logical]: https://en.wikipedia.org/wiki/Logical_shift\n[web-binstring]: https://www.baeldung.com/kotlin/int-binary-representation\n[ref-shr]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/shr.html\n[ref-ushr]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/ushr.html\n[concept-booleans]: https://exercism.org/tracks/kotlin/concepts/booleans\n"
  },
  {
    "path": "concepts/bitwise-operations/introduction.md",
    "content": "# Introduction\n\nBinary digits ultimately map directly to the transistors in your CPU or RAM, and whether each is \"on\" or \"off\".\n\nLow-level manipulation, informally called \"bit-twiddling\", is particularly important in system languages.\n\nHigher-level languages like Kotlin usually abstract away most of this detail.\nHowever, a basic range of bit-level operations [is available][ref-bitwise].\n\n## Bit-shift operations\n\n`Int` or `Long` types, signed or unsigned, can be represented as a string of 1's and 0's and manipulated as a sequence of bits.\n\nPerhaps surprisingly, `Byte` or `Short` types are not compatible with most bitwise operations in Kotlin.\nAll the examples below use 32-bit integers (`Int` or `UInt`).\n\n```kotlin\nval ns = 0b111  // 7 decimal\nInteger.toBinaryString(ns)  // => \"111\"\n```\n\nBit-shifts just move everything to the left or right by a specified number of positions.\nSome bits drop off one end, and the other end is padded with zeros or ones.\n\n- Left shift with `shl`: zero-padding.\n- Right shift with `shr` or `ushr`: zero padding for positive numbers (see later for negative numbers).\n\n```kotlin\nval ns = 0b111  // 7 decimal\nns shl 1  // => 0b1110, decimal 14\nns shr 1  // => 0b11, decimal 3\nns ushr 1  // => 0b11\n\nval nu: UInt = 0b111u  // 7 unsigned\nnu shr 1  //  => 0b11\n```\n\nEach left-shift doubles the value, and each right-shift halves it (subject to truncation).\nThis is more obvious in decimal representation:\n\n```kotlin\n3 shl 2  // => 12\n24 shr 3 // => 3\n```\n\nSuch bit-shifting is much faster than \"proper\" arithmetic, making the technique very popular in low-level coding.\n\nWith _negative integers_, we need to be a bit more careful.\n\nNegative values are stored in [two's complement][wiki-2complement] form, which means that the left-most bit is 1.\nNo problem for a left-shift, but when right-shifting how do we pad the left-most bits?\n\n```kotlin\nval ns = -0b111  // => 0b11111111111111111111111111111001\n\n// shift left: simple\nns shl 1  // => 0b11111111111111111111111111110010, decimal -14\n\n// shift right: preserves sign bit\nns shr 1  // => 0b11111111111111111111111111111100, decimal -4\n\n// unsigned shift right: left-pads with zeros\nns ushr 1 // => 0b01111111111111111111111111111100, decimal 2147483644\n```\n\nThe `shr` operator performs [arithmetic shift][wiki-arithmetic], preserving the sign bit.\n\nThe `ushr` operator performs [logical shift][wiki-logical], padding with zeros as if the number was unsigned.\n\n## Bitwise logic\n\nWe saw in the [Booleans Concept][concept-booleans] that the operators `&&` (and), `||` (or) and `!` (not) are used with boolean values.\n\nThere are equivalent operators `and`, `or`, `xor` ([exclusive-or][wiki-xor]) to compare the bits in two integers, and an `inv` (inversion) function to flip all the bits.\n\n```kotlin\n0b1011 and 0b0010 //  bit is 1 in both numbers\n// => 0b0010\n\n0b1011 or 0b0010 // bit is 1 in at least one number\n// => 0b1011\n\n0b1011 xor 0b0010 // bit is 1 in exactly one number, not both\n// => 0b1001\n\n0b1011.inv() // flip all bits (in a 32-bit signed Int)\n// => 0b11111111111111111111111111110100\n```\n\n\n[ref-bitwise]: https://kotlinlang.org/docs/numbers.html#bitwise-operations\n[wiki-xor]: https://en.wikipedia.org/wiki/Exclusive_or\n[wiki-2complement]: https://en.wikipedia.org/wiki/Two%27s_complement\n[wiki-arithmetic]: https://en.wikipedia.org/wiki/Arithmetic_shift\n[wiki-logical]: https://en.wikipedia.org/wiki/Logical_shift\n[concept-booleans]: https://exercism.org/tracks/kotlin/concepts/booleans\n"
  },
  {
    "path": "concepts/bitwise-operations/links.json",
    "content": "[\n  {\n    \"url\": \"https://kotlinlang.org/docs/numbers.html#bitwise-operations\",\n    \"description\": \"Kotlin manual: bitwise operations\"\n  }\n]\n"
  },
  {
    "path": "concepts/booleans/.meta/config.json",
    "content": "{\n  \"blurb\": \"TODO: add blurb for booleans concept\",\n  \"authors\": [\"dector\"],\n  \"contributors\": []\n}\n"
  },
  {
    "path": "concepts/booleans/about.md",
    "content": "# About\n\nBooleans in Kotlin are represented by the `Boolean` type, which values can be either `true` or `false`.\n\nKotlin supports three built-in [boolean operators][reference]: `!` (negation aka NOT), `&&` (lazy conjunction aka AND), and `||` (lazy disjunction aka OR). The `&&` and `||` operators use _short-circuit evaluation_, which means that the right-hand side of the operator is only evaluated when needed.\n\n```kotlin\ntrue || false // => true\ntrue && false // => false\n```\n\nThe three boolean operators each have a different [_operator precedence_][precedence]. As a consequence, they are evaluated in this order: `!` first, `&&` second, and finally `||`. If you want to 'escape' these rules, you can enclose a boolean expression in parentheses (`()`), as the parentheses have an even higher operator precedence.\n\n```kotlin\n!true && false   // => false\n!(true && false) // => true\n```\n\n[reference]: https://kotlinlang.org/docs/reference/basic-types.html#booleans\n[precedence]: https://kotlinlang.org/docs/reference/grammar.html#expressions\n"
  },
  {
    "path": "concepts/booleans/introduction.md",
    "content": "# Introduction\n\nBooleans in Kotlin are represented by the `Boolean` type, which values can be either `true` or `false`.\n\nKotlin supports three built-in [boolean operators][reference]: `!` (negation aka NOT), `&&` (lazy conjunction aka AND), and `||` (lazy disjunction aka OR). The `&&` and `||` operators use _short-circuit evaluation_, which means that the right-hand side of the operator is only evaluated when needed.\n"
  },
  {
    "path": "concepts/booleans/links.json",
    "content": "[\n  {\n    \"url\": \"https://kotlinlang.org/docs/reference/basic-types.html#booleans\",\n    \"description\": \"reference\"\n  },\n  {\n    \"url\": \"https://kotlinlang.org/docs/reference/grammar.html#expressions\",\n    \"description\": \"precedence\"\n  }\n]\n"
  },
  {
    "path": "concepts/chars/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"colinleach\"\n  ],\n  \"contributors\": [],\n  \"blurb\": \"Kotlin was designed from the beginning to use a large subset of Unicode characters, to represent a wide range of writing systems.\"\n}\n"
  },
  {
    "path": "concepts/chars/about.md",
    "content": "# About chars\n\nThis is potentially a _big_ subject!\nIt is possible to write a long book about it, and several people have done so (search Amazon for \"unicode book\" to see some examples).\n\n## A very brief history\n\nHandling characters in computers was much simpler in earlier decades, when programmers assumed that English was the only important language.\nSo: 26 letters, upper and lower case, 10 digits, several punctuation marks, plus a code (0x07) to ring a bell, and it all fitted into 7 bits: the [ASCII][wiki-ascii] character set.\n\nNaturally, people started asking what about à, ä and Ł, then other people started asking about ऄ, ஹ and ญ, and young people wanted emojis 😱.\nWhat to do?\n\nTo cut a long story short, many smart and patient people had to serve on committees for years, working out the details of the [Unicode][web-unicode] character set, and of encodings such as [UTF-8][wiki-utf-8], and lots of software needed a _very_ complicated rewrite.\nAlso, lots of new bugs were introduced.\n\nTo prevent _everything_ breaking, the Unicode/UTF-8 design ensures that the first 127 codes are identical to ASCII _(even the bell)_.\n\n## Characters in Kotlin\n\nLanguages designed after about 2005 have the huge advantage that a reasonably stable Unicode standard already existed.\n\nKotlin (first released in 2011) was able to assume that users would use a variety of (human) languages, and would need Unicode to express them.\n\n~~~~exercism/advanced\n[Characters][ref-char] in Kotlin are 16-bit (UTF-16) [`codepoints`][wiki-codepoint], the same as a JVM `char`.\nThis is enough to express most written alphabets, but not the entire range of emojis.\n\nThe full Unicode standard uses up to six bytes (48 bits) per character (called a [`grapheme`][wiki-grapheme]).\n\nKotlin `Strings` support this full standard by using multiple codepoints per character, when necessary.\nFor example, 😱 would be `\\uD83D` and `\\uDE31`.\n\nUnfortunately, Java has no built-in grapheme support, and for compatibility neither does Kotlin.\n\n[wiki-codepoint]: https://en.wikipedia.org/wiki/Code_point\n[wiki-grapheme]: https://en.wikipedia.org/wiki/Grapheme\n[ref-char]: https://kotlinlang.org/docs/characters.html\n~~~~\n\n\nCharacter literals are written in single-quotes, and are distinct from strings written in double quotes.\nThis is probably obvious to people from the C/C++ world, but potentially confusing to Python and JavaScript programmers.\n\n```kotlin\nval a = 'a'\na::class.qualifiedName  // => kotlin.Char\na.code  // => 97\n\nval jha = 'झ'  // Devanagari alphabet\njha.code  // => 2333\n\nval heart = '❤'  // heart emoji\nheart.code  // => 10084\n\nChar.MAX_VALUE.code // => 65535 (64k, the largest code point allowed)\n\nval not_char = 'abc' // => Too many characters in a character literal.\n```\n\nConverting between `Char` and `Int` is straightforward:\n\n```kotlin\na.code  // => 97\nChar(97) // => 'a'\n```\n\nThe compiler allows _some_ forms of integer arithmetic on `Char`s:\n\n```kotlin\n'a' + 5     // => 'f'\n'c' - 'a'   // => 2\n'c' + 'a'   // => error!\n\n'f' + ('A' - 'a')  // => 'F' (same as 'f'.uppercase()\n\n'f'.dec() // => 'e' (decrement)\n'f'.inc() // => 'g' (increment)\n```\n\n## Some functions for `Char`\n\nAs always, there are far too [many functions][ref-char-lib] to discuss here, so this is just a selection.\n\n- For appropriate alphabets, change case with [`uppercase()`][ref-uppercase] and [`lowercase()`][ref-lowercase].\n- Test case with [`isUpperCase()`][ref-isuppercase] and [`isLowerCase()`][ref-islowercase].\n- Test character type with:\n  - [`isLetter()`][ref-isletter], covers many alphabets (the Lu, Ll, Lt, Lm, and Lo categories in unicode)\n  - [`isDigit()`][ref-isdigit], in range 0..9 (the Nd category in unicode)\n  - `isLetterOrDigit()`, combines the previous two\n  - [`isWhitespace()`][ref-iswhitespace], any whitespace character (the Cc, Zp, Zl, and Zs categories in unicode)\n\n```kotlin\n'झ'.isLetter()      // => true\n'A'.isLowerCase()   // => false\n'4'.isDigit()       // => true\n'\\t'.isWhitespace() // => true  (tab character)\n```\n\nAlso, [regular expressions][ref-regex] (which will be the subject of a later Concept) allow powerful search and manipulation.\n\n## Char List and String interconversions\n\nTo convert from a `String` to a `List` of `Char`s, we can use `toList()`.\n\nTo convert a `List` of `Char`s to a `String`, there is the [`joinToString()`][ref-jointostring] function, which takes a separator (often the empty string) as argument.\n\n```kotlin\nval kt = \"kotlin\".toList()  // => [k, o, t, l, i, n]\nkt.joinToString(\"\")   // => \"kotlin\"\nkt.joinToString(\"_\")  // => \"k_o_t_l_i_n\"\n```\n\nNote that `joinToString()` operates on a List or Array.\nTo _cast_ a single `Char` to a 1-character string, use `toString()`.\n\n```kotlin\n'a'.toString() // => \"a\"\n```\n\nTo check if a character is present in a `String`, or a `Char` list or array, we have `in`, which maps to the [`contains()`][ref-contains] function.\n\n```kotlin\nval clist = \"kotlin\".toList()  // => [k, o, t, l, i, n]\n't' in clist     // => true\n't' in \"kotlin\"  // => true\n```\n\n[ref-char]: https://kotlinlang.org/docs/characters.html\n[ref-char-lib]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-char/\n[wiki-ascii]: https://en.wikipedia.org/wiki/ASCII\n[web-unicode]: https://home.unicode.org/\n[wiki-utf-8]: https://en.wikipedia.org/wiki/UTF-8\n[ref-uppercase]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/uppercase.html\n[ref-lowercase]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/lowercase.html\n[ref-isuppercase]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/is-upper-case.html\n[ref-islowercase]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/is-lower-case.html\n[ref-isletter]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/is-letter.html\n[ref-isdigit]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/is-digit.html\n[ref-iswhitespace]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/is-whitespace.html\n[ref-jointostring]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/join-to-string.html\n[ref-contains]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/contains.html\n[ref-regex]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-regex/\n"
  },
  {
    "path": "concepts/chars/introduction.md",
    "content": "# Introduction\n\nThis is potentially a _big_ subject!\nIt is possible to write a long book about it, and several people have done so (search Amazon for \"unicode book\" to see some examples).\n\n## A very brief history\n\nHandling characters in computers was much simpler in earlier decades, when programmers assumed that English was the only important language.\nSo: 26 letters, upper and lower case, 10 digits, several punctuation marks, plus a code (0x07) to ring a bell, and it all fitted into 7 bits: the [ASCII][wiki-ascii] character set.\n\nNaturally, people started asking what about à, ä and Ł, then other people started asking about ऄ, ஹ and ญ, and young people wanted emojis 😱.\nWhat to do?\n\nTo cut a long story short, many smart and patient people had to serve on committees for years, working out the details of the [Unicode][web-unicode] character set, and of encodings such as [UTF-8][wiki-utf-8], and lots of software needed a _very_ complicated rewrite.\nAlso, lots of new bugs were introduced.\n\nTo prevent _everything_ breaking, the Unicode/UTF-8 design ensures that the first 127 codes are identical to ASCII _(even the bell)_.\n\n## Characters in Kotlin\n\nLanguages designed after about 2005 have the huge advantage that a reasonably stable Unicode standard already existed.\n\nKotlin (first released in 2011) was able to assume that users would use a variety of (human) languages, and would need Unicode to express them.\n\nCharacter literals are written in single-quotes, and are distinct from strings written in double quotes.\nThis is probably obvious to people from the C/C++ world, but potentially confusing to Python and JavaScript programmers.\n\n```kotlin\nval a = 'a'\na::class.qualifiedName  // => kotlin.Char\na.code  // => 97\n\nval jha = 'झ'  // Devanagari alphabet\njha.code  // => 2333\n\nval heart = '❤'  // heart emoji\nheart.code  // => 10084\n\nChar.MAX_VALUE.code  // => 65535 (64k, the largest code point allowed)\n```\n\nConverting between `Char` and `Int` is simple:\n\n```kotlin\na.code  // => 97  (a.toInt() is deprecated)\nChar(97) // => 'a'\n```\n\nThe compiler allows _some_ forms of integer arithmetic on `Char`s:\n\n```kotlin\n'a' + 5       // => 'f'\n'c' - 'a'   // => 2\n'c' + 'a'   // => error!\n\n'f' + ('A' - 'a')  // => 'F' (same as 'f'.uppercase()\n\n'f'.dec() // => 'e' (decrement)\n'f'.inc() // => 'g' (increment)\n```\n\n## Some functions for `Char`\n\nAs always, there are far too [many functions][ref-char-lib] to discuss here, so this is just a selection.\n\n- For appropriate alphabets, change case with [`uppercase()`][ref-uppercase] and [`lowercase()`][ref-lowercase].\n- Test case with [`isUpperCase()`][ref-isuppercase] and [`isLowerCase()`][ref-islowercase].\n- Test character type with:\n    - [`isLetter()`][ref-isletter], covers many alphabets\n    - [`isDigit()`][ref-isdigit], in range 0..9\n    - `isLetterOrDigit()`, combines the previous two\n    - [`isWhitespace()`][ref-iswhitespace], any whitespace character\n\n```kotlin\n'झ'.isLetter()      // => true\n'A'.isLowerCase()   // => false\n'4'.isDigit()       // => true\n'\\t'.isWhitespace() // => true  (tab character)\n```\n\n## Char List and String interconversions\n\nFor String to Char List, we can use `toList()`.\n\nFor Char List to String, there is the [`joinToString()`][ref-jointostring] function, which takes a separator (often the empty string) as argument.\n\n```kotlin\nval kt = \"kotlin\".toList()  // => [k, o, t, l, i, n]\nkt.joinToString(\"\")   // => \"kotlin\"\nkt.joinToString(\"_\")  // => \"k_o_t_l_i_n\"\n```\n\nNote that `joinToString()` operates on a List or Array.\nTo _cast_ a single `Char` to a 1-character string, use `toString()`.\n\n```kotlin\n'a'.toString() // => \"a\"\n```\n\nTo check if a character is present in a `String`, or a `Char` list or array, we have `in`, which maps to the [`contains()`][ref-contains] function.\n\n```kotlin\nval clist = \"kotlin\".toList()  // => [k, o, t, l, i, n]\n't' in clist     // => true\n't' in \"kotlin\"  // => true\n```\n\n\n[ref-char]: https://kotlinlang.org/docs/characters.html\n[ref-char-lib]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-char/\n[wiki-ascii]: https://en.wikipedia.org/wiki/ASCII\n[web-unicode]: https://home.unicode.org/\n[wiki-utf-8]: https://en.wikipedia.org/wiki/UTF-8\n[ref-uppercase]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/uppercase.html\n[ref-lowercase]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/lowercase.html\n[ref-isuppercase]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/is-upper-case.html\n[ref-islowercase]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/is-lower-case.html\n[ref-isletter]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/is-letter.html\n[ref-isdigit]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/is-digit.html\n[ref-iswhitespace]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/is-whitespace.html\n[ref-jointostring]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/join-to-string.html\n[ref-contains]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/contains.html\n[ref-regex]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-regex/\n\n\n"
  },
  {
    "path": "concepts/chars/links.json",
    "content": "[\n  {\n    \"url\": \"https://kotlinlang.org/docs/characters.html\",\n    \"description\": \"Kotlin introduction to characters.\"\n  },\n  {\n    \"url\": \"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-char/\",\n    \"description\": \"Char type and functions\"\n  }\n]\n"
  },
  {
    "path": "concepts/conditionals/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"colinleach\"\n  ],\n  \"contributors\": [],\n  \"blurb\": \"The conditionals `if`, `else if` and `else` are used to control the flow of execution and make decisions in a program.\"\n}\n"
  },
  {
    "path": "concepts/conditionals/about.md",
    "content": "# About conditionals\n\n## Comparison operators\n\n[Comparison operators][operators] are similar to many other languages, with a few extensions.\n\nFor equality, the operators are `==` (equal) and `!=` (not equal).\n\n```Kotlin\nval txt = \"abc\"\ntxt == \"abc\" // => true\ntxt != \"abc\" // => false\n```\n\nAdditionally, the `===` and `!==` operators test for [\"referential equality\"][referential-equality]:\n`a === b` if and only if `a` and `b` point to the same object.\nThis should make more sense later in the syllabus.\n\nThe greater/less than operators are also conventional.\n\n```Kotlin\n1 < 3 // => true\n3 > 3 // => false\n3 <= 3 // => true\n4 >= 3 // => true\n```\n\n## Branching with `if`\n\nThis is the full form of an [`if` expression][if-else]:\n\n```Kotlin\nif (conditional1) {\n//    something...\n} else if (conditional2) {\n//    something...\n} else {\n//    something...\n}\n```\n\n- Parentheses `()` around each conditional are required.\n- A conditional must evaluate to a Boolean `true` or `false`.\n  Kotlin has no concept of \"truthy\" and \"falsy\" as found in some languages.\n- Braces `{}` are optional, if there is only a single expression.\n- Both `else if` and `else` are optional, and there can be multiple `else if` blocks.\n\n\n## Alternatives?\n\nBy deliberate choice, Kotlin does _not_ have the ternary operator `? :` found in Java.\nA concise form of `if ... else` is preferred:\n\n```Kotlin\nval result = if (isOk) goodValue else badValue\n\nreturn if (isOK) goodValue else badValue\n```\n\nUnlike Ruby, the concise `if ... else` form *always* needs an `else` and thus cannot be used as a guard statement:\n\n```kotlin\nreturn 42 if (isOk)\n// Syntax error: Unexpected tokens (use ';' to separate expressions on the same line).\n// Syntax error: Expecting an expression.\n\nreturn if (isOk) true\n// 'if' must have both main and 'else' branches when used as an expression.\n```\n\nNote that in Kotlin, `if` is an [_expression_][expression] returning a value.\nIt is not a [_statement_][statement] as in Java.\n\nWe will see in a later Concept that Kotlin has a powerful [`when`][when] construct, intended to replace long chains of `else if` clauses with pattern matching.\n\n\n[operators]: https://kotlinlang.org/docs/keyword-reference.html#operators-and-special-symbols\n[referential-equality]: https://kotlinlang.org/docs/equality.html#floating-point-numbers-equality\n[if-else]: https://kotlinlang.org/docs/control-flow.html#if-expression\n[when]: https://kotlinlang.org/docs/control-flow.html#when-expressions-and-statements\n[expression]: https://en.wikipedia.org/wiki/Expression_(computer_science)\n[statement]: https://en.wikipedia.org/wiki/Statement_(computer_science)\n"
  },
  {
    "path": "concepts/conditionals/introduction.md",
    "content": "# Introduction\n\n## Comparison operators\n\nComparison operators are similar to many other languages.\n\nFor equality, the operators are `==` (equal) and `!=` (not equal).\n\n```Kotlin\nval txt = \"abc\"\ntxt == \"abc\" // => true\ntxt != \"abc\" // => false\n```\n\nThe greater/less than operators are also conventional.\n\n```Kotlin\n1 < 3 // => true\n3 > 3 // => false\n3 <= 3 // => true\n4 >= 3 // => true\n```\n\n## Branching with `if`\n\nThis is the full form of an `if` expression:\n\n```Kotlin\nif (conditional1) {\n//    something...\n} else if (conditional2) {\n//    something...\n} else {\n//    something...\n}\n```\n\n- Parentheses `()` around each conditional are required.\n- A conditional must evaluate to a Boolean `true` or `false`.\n  Kotlin has no concept of \"truthy\" and \"falsy\" as found in some languages.\n- Braces `{}` are optional, if there is only a single expression.\n- Both `else if` and `else` are optional, and there can be multiple `else if` blocks.\n\n\n## Alternatives?\n\nBy deliberate choice, Kotlin does _not_ have the ternary operator `? :` found in Java.\nA concise form of `if ... else` is preferred:\n\n```Kotlin\nreturn if (isOK) goodValue else badValue\n```\n"
  },
  {
    "path": "concepts/conditionals/links.json",
    "content": "[\n  {\n    \"url\": \"https://kotlinlang.org/docs/keyword-reference.html#operators-and-special-symbols\",\n    \"description\": \"Operators reference.\"\n  },\n  {\n    \"url\": \"https://kotlinlang.org/docs/control-flow.html#if-expression\",\n    \"description\": \"Control flow introduction.\"\n  },\n  {\n    \"url\": \"https://kotlinlang.org/docs/coding-conventions.html#control-flow-statements\",\n    \"description\": \"Coding conventions.\"\n  }\n]\n"
  },
  {
    "path": "concepts/nullability/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"colinleach\"\n  ],\n  \"contributors\": [],\n  \"blurb\": \"Kotlin provides optional nullable types, plus functionality to make nullability safe and convenient to use.\"\n}\n"
  },
  {
    "path": "concepts/nullability/about.md",
    "content": "# About Nullability\n\nIn an ideal world, we could rely on everything being nicely defined, with concrete values and no gaps.\n\nThis conflicts with our everyday experience, and thus many programming languages have a way to represent the absence of a value: null or NULL, nil, None, nothing...\n\nThis was easy to introduce (back in 1965), but soon led to regrets.\nThe inventor later called it his [\"Billion Dollar Mistake\"][web-mistake].\n\nIn recent decades, language designers have explored many ways to make nulls available but (mostly) safe.\n\nKotlin has a few [general principles][ref-null-safety], which [differ significantly from Java][ref-java2kotlin].\n_The differences mean that Kotlin has special functionality to deal with Java interop, though details are beyond the scope of this Concept._\n\n- Kotlin has a special `null` value.\n- All types _default_ to being non-nullable (i.e. can not be `null`) .\n- All types can be _nullable_, but this must be explicitly done.\n- Functions which might fail with an exception are likely to have a variant with a nullable return value.\n- Special, highly terse syntax tries to make testing for and responding to nulls as easy as possible.\n\n## Creating nullable variables\n\nA type can be made [nullable][ref-nullable-type] by adding the `?` suffix (e.g. `String?` instead of `String`).\n\n```kotlin\nvar a = \"Kotlin\"  // inferred type is String\na = null          // => Error: Null can not be a value of a non-null type String\n\nvar b: String? = \"Kotlin\"  // nullable type\nb = null                   // => b is now null\nb == null                  // => true\n```\n\n## Useful operators and functions\n\n### The [safe call operator][ref-safe-call] `?.`\n\nFor a non-nullable `String`, we can get the `.length` property.\n\nA nullable `String?` fails with the same syntax, but using `?.length` allows for the possibility of a `null`.\nThe return type is `Int?`.\n\n```kotlin\nvar a = \"Kotlin\"\na.length  // => 6\n\n// b is still null\nb.length  // => Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?\nb?.length // => null\na?.length // => 6\n```\n\nAs we saw in the last line above, `?.` also works with non-nullable types.\n\n### The [Elvis operator][ref-elvis] `?:`\n\nExtending the idea of the safe-call operator, the [Elvis operator][wiki-elvis] lets us supply a default value to replace `null`.\n\n```kotlin\n// b is still null\nb?.length ?: -1  // => -1, in place of null\na?.length ?: -1  // => 6, as before\n```\n\n### [Not-null assertion operator][ref-not-null] `!!`\n\nWith this operator, a nullable type is forced to be treated as non-null, when the programmer is confident about this.\nPerhaps we sometimes understand the program logic better than an over-cautious compiler?\n\n```kotlin\n// b is still a String?\nb = \"Kotlin?\"\nb!!.length  // => 7\n```\n\nThe responsibility is now on us: if `b` is still `null` we get a `NullPointerException`.\n\n### [Let function][ref-let] `?.let`\n\nIf passing a nullable item to a block of code, we could do specific null checks `if (item != null) { do something }`.\n\nIt is simpler and more idiomatic to use `item?.let { do something }`,\nThe `do something` will only execute when `item` is not null.\n\n### Functions of type `somethingOrNone()`\n\nSome functions may fail, for example when asking for an invalid index in a string or list.\n\nRather than throwing an exception, we could use the [`...OrNull` variant][ref-elem-at-or-null] of the function, to get (in this case) an `Int?` return value.\n\n```kotlin\nval str = \"Kotlin\"\nstr.elementAtOrNull(10)  // => null\nstr.elementAt(10)  // => StringIndexOutOfBoundsException: String index out of range: 10\n```\n\n[ref-java2kotlin]: https://kotlinlang.org/docs/java-to-kotlin-nullability-guide.html\n[web-mistake]: https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/\n[ref-null-safety]: https://kotlinlang.org/docs/null-safety.html\n[ref-elvis]: https://kotlinlang.org/docs/null-safety.html#elvis-operator\n[wiki-elvis]: https://en.wikipedia.org/wiki/Elvis_operator\n[ref-nullable-type]: https://kotlinlang.org/docs/null-safety.html#nullable-types-and-non-nullable-types\n[ref-safe-call]: https://kotlinlang.org/docs/null-safety.html#safe-call-operator\n[ref-not-null]: https://kotlinlang.org/docs/null-safety.html#not-null-assertion-operator\n[ref-let]: https://kotlinlang.org/docs/null-safety.html#let-function\n[ref-elem-at-or-null]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/element-at-or-null.html\n"
  },
  {
    "path": "concepts/nullability/introduction.md",
    "content": "# Introduction\n\nIn an ideal world, we could rely on everything being nicely defined, with concrete values and no gaps.\n\nThis conflicts with our everyday experience, and thus many programming languages have a way to represent the absence of a value: null or NULL, nil, None, nothing...\n\nThis was easy to introduce (back in 1965), but soon led to regrets.\nThe inventor later called it his \"Billion Dollar Mistake\".\n\nIn recent decades, language designers have explored many ways to make nulls available but (mostly) safe.\n\nKotlin has a few [general principles][ref-null-safety], which differ significantly from Java.\n\n\n- Kotlin has a special `null` value.\n- All types _default_ to being non-nullable.\n- Most types can be _made_ nullable, but the programmer must explicitly order this.\n- Functions which might fail with an exception are likely to have a variant with a nullable return value.\n- Special, highly terse syntax tries to make testing for and responding to nulls as easy as possible.\n\n## Creating nullable variables\n\nStandard types generally have a nullable equivalent, with a `?` suffix: for example `String?` instead of `String`.\n\n```kotlin\nvar a = \"Kotlin\"  // inferred type is String\na = null          // => Error: Null can not be a value of a non-null type String\n\nvar b: String? = \"Kotlin\"  // nullable type\nb = null                   // => b is now null\nb == null                  // => true\n```\n\n## Useful operators and functions\n\n### The safe call operator `?.`\n\nFor a non-nullable `String`, we can get the `.length` property.\n\nA nullable `String?` fails with the same syntax, but using `?.length` allows for the possibility of a `null`.\nThe return type is `Int?`.\n\n```kotlin\nvar a = \"Kotlin\"\na.length  // => 6\n\n// b is still null\nb.length  // => Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?\nb?.length // => null\na?.length // => 6\n```\n\nAs we saw in the last line above, `?.` also works with non-nullable types.\n\n### The Elvis operator `?:`\n\nExtending the idea of the safe-call operator, the [Elvis operator][wiki-elvis] lets us supply a default value to replace `null`.\n\n```kotlin\n// b is still null\nb?.length ?: -1  // => -1, in place of null\na?.length ?: -1  // => 6, as before\n```\n\n### Not-null assertion operator `!!`\n\nWith this operator, a nullable type is forced to be treated as non-null, when the programmer is confident about this.\nPerhaps we sometimes understand the program logic better than an over-cautious compiler?\n\n```kotlin\n// b is still a String?\nb = \"Kotlin?\"\nb!!.length  // => 7\n```\n\nThe responsibility is now on us: if `b` is still `null` we get a `NullPointerException`.\n\n### Let function `?.let`\n\nIf passing a nullable item to a block of code, we could do specific null checks `if (item != null) { do something }`.\n\nIt is simpler and more idiomatic to use `item?.let { do something }`,\nThe `do something` will only execute when `item` is not null.\n\n### Functions of type `somethingOrNone()`\n\nSome functions may fail, for example when asking for an invalid index in a string or list.\n\nRather than throwing an exception, we could use the `...OrNull` variant of the function, to get (in this case) an `Int?` return value.\n\n```kotlin\nval str = \"Kotlin\"\nstr.elementAtOrNull(10)  // => null\nstr.elementAt(10)  // => StringIndexOutOfBoundsException: String index out of range: 10\n```\n\n\n[web-mistake]: https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/\n[ref-null-safety]: https://kotlinlang.org/docs/null-safety.html\n[wiki-elvis]: https://en.wikipedia.org/wiki/Elvis_operator\n"
  },
  {
    "path": "concepts/nullability/links.json",
    "content": "[\n  {\n    \"url\": \"https://kotlinlang.org/docs/null-safety.html\",\n    \"description\": \"Kotlin introduction to null safety.\"\n  },\n  {\n    \"url\": \"https://kotlinlang.org/docs/java-to-kotlin-nullability-guide.html\",\n    \"description\": \"Nullability guide for Java to Kotlin migration.\"\n  }\n]\n"
  },
  {
    "path": "concepts/strings/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"colinleach\"\n  ],\n  \"contributors\": [],\n  \"blurb\": \"Strings are an immutable sequence of Unicode characters.\"\n}\n"
  },
  {
    "path": "concepts/strings/about.md",
    "content": "# About Strings\n\nA [`string`][ref-string] in Kotlin is an immutable sequence of Unicode characters.\n\n[`Immutable`][wiki-immutable] means that any operation on a string must return a new string: the original string can never change.\n\n[`Unicode`][wiki-unicode] means that most of the world's writing systems can be represented, but (in contrast to older languages such as C) there is no 1:1 mapping between characters and bytes.\nThis will be discussed further in the [`Chars`][concept-chars] Concept.\n\nA string is surrounded by double-quotes `\" \"`.\n\nSome characters need escaping: `\\\\`, plus the usual non-printing characters such as `\\t` (tab) and `\\n` (newline).\n\n```kotlin\nval s = \"Escape backslash \\\\.\"\n// Escape backslash \\.\n```\n\nMulti-line strings are surrounded by 3 double-quotes, and can contain arbitrary text (no need for escaping).\n\n```kotlin\nval multi = \"\"\"I'm a\n    multi-line\n    string with special characters \\ \\t \"\"\"\n//I'm a\n//    multi-line\n//    string with special characters  \\ \\t \n```\n\nUse [trimIndent][trimIndent-doc] to remove the common indenting from the lines.\nThis is useful for formatting the string:\n\n```kotlin\nval multi = \"\"\"\n    I'm a\n      multi-line\n    string\"\"\".trimIndent()\n\n//I'm a\n//  multi-line\n//string\n```\n\nAlternatively, [trimMargin][trimMargin-doc] lets you specify a delimiter.\nEach line in the `String` then begins after the delimiter.\nThe delimiter defaults to `|`, but you can specify a different delimiter as a parameter.\nFor example:\n\n```kotlin\nval multi = \"\"\"\n    |I'm a\n    |  multi-line\n    |string\"\"\".trimMargin()\n\n//I'm a\n//  multi-line\n//string\n\nval multi2 = \"\"\"\n    start>I'm a\n    start>  multi-line\n    start>string\"\"\".trimMargin(\"start>\")\n\n//I'm a\n//  multi-line\n//string\n```\n\nStrings can be concatenated with `+`, but this is best limited to short and simple cases.\nThere are other and often better options.\n\n## String templates\n\n[`Templates`][ref-templates] refers to what some other languages call \"interpolation\".\n\nIf a string contains a dollar sign `$`, followed by an identifier, or contains braces (`{expression}`) surrounding an expression, those are substituted by respectively the value or the result of the expression.\n\n```kotlin\nval x = 42\nval st = \"x is $x, x squared is {x * x}\"\n// x is 42, x squared is 1764\n```\n\n## String formatting\n\nOn the JVM platform (only), `String.format()` allows more precise formatting than string templates, with [syntax][web-formats] similar to the (_very old!_) [`printf`][wiki-printf] functions.\n\n```kotlin\nString.format(\"%s %.3f\", \"π ≈\", 3.14159)\n//π ≈ 3.142\n```\n\n~~~~exercism/advanced\nKotlin can be compiled to several different targets: the Java Virtual Machine, JavaScript, native binaries for Linux, Windows, Android and Apple, plus two variants of WebAssembly.\n\nEssentially the same code can be used for each, but different capabilities in the target platforms mean some differences in which standard library functions are supported.\n\nExercism currently uses the JVM for testing.\n~~~~\n\n## String functions\n\nKotlin provides _many_ [`functions`][ref-string-functions] to manipulate strings.\n\nMostly, these are [`extensions functions`][ref-extensions] rather than members of the `String` class, though this has little effect on how we use them.\n\n~~~~exercism/note\nKotlin's rather complex [documentation][ref-string-functions] pages hide extension functions in the default view.\nAt moment of writing this, the most valuable content is hidden in a tab named `Members & Extensions`.\nClick it to expand this section and see all the members and extensions available on the `String` class.\n\n[ref-string-functions]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/\n~~~~\n\nThe following example shows just a small selection of what is available:\n\n```kotlin\nval str = \"Hello World!\"\n\nstr.length              // => 12 (a property, not a function)\nstr.elementAt(6)        // => W\nstr.elementAtOrNull(20) // => null (index out of range)\nstr.substring(6, 11)    // => \"World\"\nstr.substringAfter(\" \") // => \"World!\"\n\nstr.lowercase()         // => \"hello world!\"\nstr.uppercase()         // => \"HELLO WORLD!\"\n\nstr.startsWith(\"Hel\")   // => true\nstr.endsWith(\"xyz\")     // => false\nstr.indexOf(\"0\")        // => 4\n\nstr.toCharArray()       // => [H, e, l, l, o,  , W, o, r, l, d, !]\n\"42\".toInt() + 1        // => 43  (parsing; see also toFloat)\n\n\"Howdy!  \".trim()       // => \"Howdy\"\n```\n\n## Building a string\n\nSometimes a long string needs to be built up in stages, for example within a loop.\n\nConcatenating strings with `+` soon becomes neither elegant nor performant: immutability means that there is a _lot_ of copying required.\n\nKotlin has various more efficient ways to combine multiple string:\n\n- String templates, described above.\n- [`joinToString()][ref-jointostring], which will be covered in the [Lists][concept-lists] Concept.\n- Java's [`StringBuilder`][ref-stringbuilder], which is not regarded as particularly idiomatic Kotlin.\n- Kotlin's [`buildString()`][ref-buildstring], which wraps `StringBuilder` in a more concise and idiomatic syntax.\nThis takes string-building logic as a lambda argument, which will be discussed in a later Concept.\n\nIn essence, a `StringBuilder` is a list-like structure, with many convenient methods.\nThis is a small selection:\n\n- [`append()`][ref-sb-append] to add to the end.\n- [`insert()`][ref-sb-insert] to add at a specified position.\n- [`deleteAt()`][ref-sb-deleteat] and [`deleteRange()`][ref-sb-deleterange] to remove from specified position(s).\n- `toString()` to convert to a normal string at the end: concatenating everything in a single, performant operation.\n\n```kotlin\n// Available, not recommended\nval sb = StringBuilder()\nsb.append(\"Hello \")\nsb.append(\"World!\")\nsb.toString()\n//Hello World!\n```\n\nA `buildString()` example, using syntax from later Concepts:\n\n```kotlin\nval countDown = buildString {\n    for (i in 5 downTo 1) {\n        append(i)\n        append(\"_\")\n    }\n}\n// countDown is \"5_4_3_2_1_\"\n```\n\n\n[ref-string]: https://kotlinlang.org/docs/strings.html\n[wiki-immutable]: https://en.wikipedia.org/wiki/Immutable_object\n[wiki-unicode]: https://en.wikipedia.org/wiki/Unicode\n[web-formats]: https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html#summary\n[wiki-printf]: https://en.wikipedia.org/wiki/Printf\n[ref-stringbuilder]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-string-builder/\n[ref-extensions]: https://kotlinlang.org/docs/extensions.html#extensions.md\n[ref-string-functions]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/\n[concept-chars]: https://exercism.org/tracks/kotlin/concepts/chars\n[concept-lists]: https://exercism.org/tracks/kotlin/concepts/lists\n[ref-templates]: https://kotlinlang.org/docs/strings.html#string-templates\n[ref-sb-append]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-string-builder/#9100522%2FFunctions%2F-705004581\n[ref-sb-insert]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-string-builder/#-132863384%2FFunctions%2F-705004581\n[ref-sb-deleteat]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-string-builder/#-386007892%2FFunctions%2F-956074838\n[ref-sb-deleterange]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-string-builder/#-1622040372%2FFunctions%2F-956074838\n[ref-buildstring]: https://kotlinlang.org/docs/java-to-kotlin-idioms-strings.html#build-a-string\n[ref-jointostring]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/join-to-string.html\n[trimIndent-doc]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/trim-indent.html\n[trimMargin-doc]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/trim-margin.html\n"
  },
  {
    "path": "concepts/strings/introduction.md",
    "content": "# Introduction\n\nA [`string`][ref-string] in Kotlin is an immutable sequence of Unicode characters.\n\n[`Immutable`][wiki-immutable] means that any operation on a string must return a new string: the original string can never change.\n\n[`Unicode`][wiki-unicode] means that most of the world's writing systems can be represented, but (in contrast to older languages such as C) there is no 1:1 mapping between characters and bytes.\n\nA string is surrounded by double-quotes `\" \"`.\n\nSome characters need escaping: `\\\\`, plus the usual non-printing characters such as `\\t` (tab) and `\\n` (newline).\n\n```kotlin\nval s = \"Escape backslash \\\\.\"\n// Escape backslash \\.\n```\n\nMulti-line strings are surrounded by 3 double-quotes, and can contain arbitrary text (no need for escaping).\n\n```kotlin\nval multi = \"\"\"I'm a\n    multi-line\n    string with special characters \\ \\t \"\"\"\n//I'm a\n//    multi-line\n//    string with special characters  \\ \\t \n```\n\nUse [trimIndent][trimIndent-doc] to remove the common indenting from the lines.\nThis is useful for formatting the string:\n\n```kotlin\nval multi = \"\"\"\n    I'm a\n      multi-line\n    string\"\"\".trimIndent()\n\n//I'm a\n//  multi-line\n//string\n```\n\nAlternatively, [trimMargin][trimMargin-doc] lets you specify a delimiter.\nEach line in the `String` then begins after the delimiter.\nThe delimiter defaults to `|`, but you can specify a different delimiter as a parameter.\nFor example:\n\n```kotlin\nval multi = \"\"\"\n    |I'm a\n    |  multi-line\n    |string\"\"\".trimMargin()\n\n//I'm a\n//  multi-line\n//string\n\nval multi2 = \"\"\"\n    start>I'm a\n    start>  multi-line\n    start>string\"\"\".trimMargin(\"start>\")\n\n//I'm a\n//  multi-line\n//string\n```\n\nStrings can be concatenated with `+`, but this is best limited to short and simple cases.\nThere are other and often better options.\n\n## String templates\n\nThis refers to what some other languages call \"interpolation\".\n\nIf a string contains a dollar sign `$`, followed by an identifier, or contains braces (`{expression}`) surrounding an expression, those are substituted by respectively the value or the result of the expression.\n\n```kotlin\nval x = 42\nval st = \"x is $x, x squared is {x * x}\"\n// x is 42, x squared is 1764\n```\n\nThe braces `{ }` are needed around expressions when parsing would otherwise be ambiguous.\n\nIn general, use of string templates is a more efficient and idiomatic way to combine strings than using `+`.\n\n## String functions\n\nKotlin provides _many_ [`functions`][ref-string-functions] to manipulate strings.\n\nMostly, these are [`extensions functions`][ref-extensions] rather than members of the `String` class, though this has little effect on how we use them.\n\n~~~~exercism/note\nKotlin's rather complex [documentation][ref-string-functions] pages hide extension functions in the default view.\nBe sure to click `Members & Extensions` to expand this section.\n\n[ref-string-functions]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/\n~~~~\n\nThe following examples show just a small selection of what is available:\n\n```kotlin\nval str = \"Hello World!\"\n\nstr.length              // => 12 (a property, not a function)\nstr.elementAt(6)        // => W\nstr.elementAtOrNull(20) // => null (index out of range)\nstr.substring(6, 11)    // => \"World\"\nstr.substringAfter(\" \") // => \"World!\"\n\nstr.lowercase()         // => \"hello world!\"\nstr.uppercase()         // => \"HELLO WORLD!\"\n\nstr.startsWith(\"Hel\")   // => true\nstr.endsWith(\"xyz\")     // => false\nstr.indexOf(\"0\")        // => 4\n\nstr.toCharArray()       // => [H, e, l, l, o,  , W, o, r, l, d, !]\n\"42\".toInt() + 1        // => 43  (parsing; see also toFloat)\n\n\"Howdy!  \".trim()       // => \"Howdy\"\n```\n\n\n[ref-string]: https://kotlinlang.org/docs/strings.html\n[wiki-immutable]: https://en.wikipedia.org/wiki/Immutable_object\n[wiki-unicode]: https://en.wikipedia.org/wiki/Unicode\n[ref-stringbuilder]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-string-builder/\n[ref-extensions]: https://kotlinlang.org/docs/extensions.html#extensions.md\n[ref-string-functions]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/\n[trimIndent-doc]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/trim-indent.html\n[trimMargin-doc]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/trim-margin.html\n"
  },
  {
    "path": "concepts/strings/links.json",
    "content": "[\n  {\n    \"url\": \"https://kotlinlang.org/docs/strings.html\",\n    \"description\": \"Kotlin string introduction\"\n  },\n  {\n    \"url\": \"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/\",\n    \"description\": \"String functions\"\n  },\n  {\n    \"url\": \"https://kotlinlang.org/docs/strings.html#string-templates\",\n    \"description\": \"String Templates\"\n  }\n]\n"
  },
  {
    "path": "config.json",
    "content": "{\n  \"language\": \"Kotlin\",\n  \"slug\": \"kotlin\",\n  \"active\": true,\n  \"status\": {\n    \"concept_exercises\": false,\n    \"test_runner\": true,\n    \"representer\": false,\n    \"analyzer\": false\n  },\n  \"blurb\": \"Kotlin is a pragmatic programming language for JVM and Android that combines OO and functional features and is focused on interoperability, safety, clarity and tooling support.\",\n  \"version\": 3,\n  \"online_editor\": {\n    \"indent_style\": \"space\",\n    \"indent_size\": 4,\n    \"highlightjs_language\": \"kotlin\"\n  },\n  \"test_runner\": {\n    \"average_run_time\": 4\n  },\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/%{pascal_slug}.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/%{pascal_slug}Test.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/%{pascal_slug}.kt\"\n    ],\n    \"exemplar\": [\n      \".meta/src/reference/kotlin/%{pascal_slug}.kt\"\n    ]\n  },\n  \"exercises\": {\n    \"concept\": [\n      {\n        \"slug\": \"lucians-luscious-lasagna\",\n        \"name\": \"Lucian's Luscious Lasagna\",\n        \"uuid\": \"de14936d-28d7-4531-9761-69deba31a7ca\",\n        \"concepts\": [\n          \"basics\"\n        ],\n        \"prerequisites\": [],\n        \"status\": \"wip\"\n      },\n      {\n        \"slug\": \"annalyns-infiltration\",\n        \"name\": \"Annalyn's Infiltration\",\n        \"uuid\": \"5a0af671-2549-411c-860a-f36859b429e5\",\n        \"concepts\": [\n          \"booleans\"\n        ],\n        \"prerequisites\": [\n          \"basics\"\n        ],\n        \"status\": \"wip\"\n      },\n      {\n        \"slug\": \"log-levels\",\n        \"name\": \"log-levels\",\n        \"uuid\": \"ef54c5e6-7d31-42d1-a300-e405169dbd7f\",\n        \"concepts\": [\n          \"strings\"\n        ],\n        \"prerequisites\": [\n          \"basics\"\n        ],\n        \"status\": \"wip\"\n      }\n    ],\n    \"practice\": [\n      {\n        \"slug\": \"accumulate\",\n        \"name\": \"Accumulate\",\n        \"uuid\": \"86015770-603b-44cf-aedf-f2a7cf79c841\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 1,\n        \"status\": \"deprecated\",\n        \"topics\": [\n          \"lists\"\n        ]\n      },\n      {\n        \"slug\": \"binary\",\n        \"name\": \"Binary\",\n        \"uuid\": \"def44955-c048-4b74-8777-2fb7d779b09e\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 1,\n        \"status\": \"deprecated\",\n        \"topics\": [\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"hello-world\",\n        \"name\": \"Hello World\",\n        \"uuid\": \"58c16459-348a-4536-8228-43379174735e\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 1,\n        \"topics\": [\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"hexadecimal\",\n        \"name\": \"Hexadecimal\",\n        \"uuid\": \"13b1a62e-8e0e-4d57-b8c9-341b41f25cf5\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 1,\n        \"status\": \"deprecated\",\n        \"topics\": [\n          \"string\",\n          \"integers\"\n        ]\n      },\n      {\n        \"slug\": \"reverse-string\",\n        \"name\": \"Reverse String\",\n        \"uuid\": \"95d495a6-b1a2-42d5-8190-443d6f94e80b\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 1,\n        \"topics\": [\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"strain\",\n        \"name\": \"Strain\",\n        \"uuid\": \"8ae8492d-620c-4446-9928-5b4d78d496d9\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 1,\n        \"status\": \"deprecated\",\n        \"topics\": [\n          \"arrays\",\n          \"filtering\"\n        ]\n      },\n      {\n        \"slug\": \"bob\",\n        \"name\": \"Bob\",\n        \"uuid\": \"f3713067-7f37-4dd6-a189-c80f46dab8ec\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 2,\n        \"topics\": [\n          \"booleans\",\n          \"conditionals\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"collatz-conjecture\",\n        \"name\": \"Collatz Conjecture\",\n        \"uuid\": \"ab52d0f4-a001-4d44-951e-0cfc396374f3\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 2,\n        \"topics\": [\n          \"conditionals\",\n          \"exception_handling\",\n          \"integers\",\n          \"math\",\n          \"recursion\"\n        ]\n      },\n      {\n        \"slug\": \"darts\",\n        \"name\": \"Darts\",\n        \"uuid\": \"c2b49ff6-e7bf-40bb-b619-9cdfaa43c065\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 2,\n        \"topics\": [\n          \"pattern_matching\",\n          \"conditionals\",\n          \"math\"\n        ]\n      },\n      {\n        \"slug\": \"eliuds-eggs\",\n        \"name\": \"Eliud's Eggs\",\n        \"uuid\": \"88e7d43f-87f8-4c00-a463-f1593d725e18\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 2\n      },\n      {\n        \"slug\": \"etl\",\n        \"name\": \"ETL\",\n        \"uuid\": \"f0f297f2-429f-4626-8b7f-0706a1e8f255\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 2,\n        \"topics\": [\n          \"lists\",\n          \"maps\",\n          \"transforming\"\n        ]\n      },\n      {\n        \"slug\": \"grains\",\n        \"name\": \"Grains\",\n        \"uuid\": \"1fa1e0f9-6410-4197-8778-debeb274e6d4\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 2,\n        \"topics\": [\n          \"integers\"\n        ]\n      },\n      {\n        \"slug\": \"isogram\",\n        \"name\": \"Isogram\",\n        \"uuid\": \"e5338be9-6f51-4448-9b10-20de7b1338b9\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 2,\n        \"topics\": [\n          \"conditionals\",\n          \"loops\",\n          \"parsing\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"leap\",\n        \"name\": \"Leap\",\n        \"uuid\": \"639e59b6-84aa-4f13-9718-537606703c43\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 2,\n        \"topics\": [\n          \"conditionals\",\n          \"integers\"\n        ]\n      },\n      {\n        \"slug\": \"nucleotide-count\",\n        \"name\": \"Nucleotide Count\",\n        \"uuid\": \"62bd648a-e959-4ec4-8a5f-09e08fa0b2c8\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 2,\n        \"topics\": [\n          \"conditionals\",\n          \"exception_handling\",\n          \"integers\",\n          \"maps\",\n          \"parsing\",\n          \"searching\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"protein-translation\",\n        \"name\": \"Protein Translation\",\n        \"uuid\": \"368ba5ef-8c54-4016-93df-3a7d3b136243\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 2,\n        \"topics\": [\n          \"algorithms\",\n          \"lists\",\n          \"conditionals\",\n          \"loops\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"rna-transcription\",\n        \"name\": \"RNA Transcription\",\n        \"uuid\": \"9772c916-c619-445c-834d-af7dbf1ad2d9\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 2,\n        \"topics\": [\n          \"loops\",\n          \"maps\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"sum-of-multiples\",\n        \"name\": \"Sum of Multiples\",\n        \"uuid\": \"d3f960e5-cf19-4308-a1bc-897777f62689\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 2,\n        \"topics\": [\n          \"arrays\",\n          \"conditionals\",\n          \"integers\",\n          \"loops\",\n          \"math\"\n        ]\n      },\n      {\n        \"slug\": \"triangle\",\n        \"name\": \"Triangle\",\n        \"uuid\": \"e282536b-267f-490c-a453-758135051a54\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 2,\n        \"topics\": [\n          \"conditionals\",\n          \"exception_handling\",\n          \"integers\",\n          \"recursion\"\n        ]\n      },\n      {\n        \"slug\": \"two-fer\",\n        \"name\": \"Two Fer\",\n        \"uuid\": \"40f85461-c256-4b96-8d5b-0509f42fab17\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 2,\n        \"topics\": [\n          \"conditionals\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"acronym\",\n        \"name\": \"Acronym\",\n        \"uuid\": \"d8288e46-2e8c-42e4-8e14-20b1efd0f574\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"loops\",\n          \"parsing\",\n          \"searching\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"allergies\",\n        \"name\": \"Allergies\",\n        \"uuid\": \"a826af04-b7f3-426e-9bce-42375d0d928b\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"booleans\",\n          \"conditionals\",\n          \"enumerations\",\n          \"integers\",\n          \"lists\",\n          \"loops\"\n        ]\n      },\n      {\n        \"slug\": \"anagram\",\n        \"name\": \"Anagram\",\n        \"uuid\": \"f754e1cc-cb88-4776-ab11-3e6ae8362d5a\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"arrays\",\n          \"conditionals\",\n          \"equality\",\n          \"lists\",\n          \"loops\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"armstrong-numbers\",\n        \"name\": \"Armstrong Numbers\",\n        \"uuid\": \"3905dff6-7835-44ff-a8c9-7f4d184ab714\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"algorithms\",\n          \"loops\",\n          \"math\"\n        ]\n      },\n      {\n        \"slug\": \"binary-search\",\n        \"name\": \"Binary Search\",\n        \"uuid\": \"c8815b6c-19b8-4f4d-9be4-6717e933591a\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"arrays\",\n          \"generics\",\n          \"recursion\",\n          \"searching\"\n        ]\n      },\n      {\n        \"slug\": \"clock\",\n        \"name\": \"Clock\",\n        \"uuid\": \"1dcefdea-5447-4622-a064-079aad781398\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"equality\",\n          \"integers\",\n          \"logic\",\n          \"object_oriented_programming\",\n          \"strings\",\n          \"time\"\n        ]\n      },\n      {\n        \"slug\": \"crypto-square\",\n        \"name\": \"Crypto Square\",\n        \"uuid\": \"2928cf06-dab8-4522-a6d8-b2a15d7d356b\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"strings\",\n          \"text_formatting\",\n          \"transforming\"\n        ]\n      },\n      {\n        \"slug\": \"difference-of-squares\",\n        \"name\": \"Difference of Squares\",\n        \"uuid\": \"d54a68fc-02dd-45ee-8c6f-3efb781ed0d2\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"integers\",\n          \"loops\",\n          \"math\"\n        ]\n      },\n      {\n        \"slug\": \"dnd-character\",\n        \"name\": \"D&D Character\",\n        \"uuid\": \"a550dafa-bcec-448c-a7dd-af0ebd4e1070\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"integers\",\n          \"randomness\"\n        ]\n      },\n      {\n        \"slug\": \"flatten-array\",\n        \"name\": \"Flatten Array\",\n        \"uuid\": \"c67907b6-0d8b-4b12-9c41-6069845952a3\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"stacks\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"gigasecond\",\n        \"name\": \"Gigasecond\",\n        \"uuid\": \"1eb4c9d3-0085-4ca3-b1bb-9a20b88a1e7f\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"dates\",\n          \"integers\",\n          \"time\"\n        ]\n      },\n      {\n        \"slug\": \"hamming\",\n        \"name\": \"Hamming\",\n        \"uuid\": \"7151ff23-ebc6-43d7-86b6-81cf0dd45309\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"integers\",\n          \"loops\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"pangram\",\n        \"name\": \"Pangram\",\n        \"uuid\": \"0e9ca09d-c32e-4fed-930f-1b7c10b67dc2\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"pattern_matching\",\n          \"regular_expressions\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"perfect-numbers\",\n        \"name\": \"Perfect Numbers\",\n        \"uuid\": \"ad7c8fd8-acf0-40d0-8a30-d959c4b0252a\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"enumerations\",\n          \"exception_handling\",\n          \"filtering\",\n          \"integers\",\n          \"math\"\n        ]\n      },\n      {\n        \"slug\": \"phone-number\",\n        \"name\": \"Phone Number\",\n        \"uuid\": \"2c8c1c16-bbb8-49e5-a248-f7a473c2bc86\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"conditionals\",\n          \"pattern_matching\",\n          \"regular_expressions\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"prime-factors\",\n        \"name\": \"Prime Factors\",\n        \"uuid\": \"0e92ba19-2727-4a5e-be38-e88878322c53\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"arrays\",\n          \"conditionals\",\n          \"integers\",\n          \"lists\",\n          \"loops\",\n          \"math\"\n        ]\n      },\n      {\n        \"slug\": \"raindrops\",\n        \"name\": \"Raindrops\",\n        \"uuid\": \"93ee76ba-d19f-4c72-b011-676f40dcda5e\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"conditionals\",\n          \"integers\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"resistor-color\",\n        \"name\": \"Resistor Color\",\n        \"uuid\": \"9d62b45c-1acf-4ae6-b990-73e5bc2b5893\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"lists\"\n        ]\n      },\n      {\n        \"slug\": \"resistor-color-duo\",\n        \"name\": \"Resistor Color Duo\",\n        \"uuid\": \"84bdc53f-aa1f-4ddf-9c5d-95b03cfff72d\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"lists\"\n        ]\n      },\n      {\n        \"slug\": \"resistor-color-trio\",\n        \"name\": \"Resistor Color Trio\",\n        \"uuid\": \"ae4df67d-c848-42e6-9fd7-d3cec83c1691\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"math\",\n          \"type_conversion\",\n          \"lists\"\n        ]\n      },\n      {\n        \"slug\": \"rotational-cipher\",\n        \"name\": \"Rotational Cipher\",\n        \"uuid\": \"7c24087a-ca61-48d3-9cb9-c3fde2edba86\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"cryptography\",\n          \"integers\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"run-length-encoding\",\n        \"name\": \"Run-Length Encoding\",\n        \"uuid\": \"483b5124-b5b2-4bb0-aa69-b04e3ea6aeb6\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"loops\",\n          \"regular_expressions\",\n          \"strings\",\n          \"transforming\",\n          \"type_conversion\"\n        ]\n      },\n      {\n        \"slug\": \"scale-generator\",\n        \"name\": \"Scale Generator\",\n        \"uuid\": \"dfa35a61-07da-4317-8c25-0c630e551d8c\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"status\": \"deprecated\",\n        \"topics\": [\n          \"lists\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"scrabble-score\",\n        \"name\": \"Scrabble Score\",\n        \"uuid\": \"4d8a68eb-eee9-4c51-97b8-57f3b69f5970\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"games\",\n          \"loops\",\n          \"pattern_matching\",\n          \"strings\",\n          \"transforming\"\n        ]\n      },\n      {\n        \"slug\": \"secret-handshake\",\n        \"name\": \"Secret Handshake\",\n        \"uuid\": \"feee3ee9-81d5-4a4f-ad98-e1ecf21757ed\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"bitwise_operations\",\n          \"conditionals\",\n          \"cryptography\",\n          \"enumerations\",\n          \"integers\",\n          \"loops\",\n          \"transforming\"\n        ]\n      },\n      {\n        \"slug\": \"series\",\n        \"name\": \"Series\",\n        \"uuid\": \"9caa5fd9-a774-4d4c-951d-053a4f3f2726\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"conditionals\",\n          \"lists\",\n          \"loops\",\n          \"strings\",\n          \"type_conversion\"\n        ]\n      },\n      {\n        \"slug\": \"space-age\",\n        \"name\": \"Space Age\",\n        \"uuid\": \"a91ce7e9-9a2a-44de-b10c-cc1be63df2a1\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"conditionals\",\n          \"floating_point_numbers\"\n        ]\n      },\n      {\n        \"slug\": \"sublist\",\n        \"name\": \"Sublist\",\n        \"uuid\": \"ebfdf40a-1fde-4c88-aa93-95e3190f5261\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"enumerations\",\n          \"generics\",\n          \"lists\",\n          \"loops\",\n          \"searching\"\n        ]\n      },\n      {\n        \"slug\": \"word-count\",\n        \"name\": \"Word Count\",\n        \"uuid\": \"3b8b77ef-da2d-499d-9513-8fe771e86b3e\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"conditionals\",\n          \"integers\",\n          \"loops\",\n          \"maps\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"yacht\",\n        \"name\": \"Yacht\",\n        \"uuid\": \"2702ffe9-26c3-4f68-86dc-2993dfa2de91\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 3,\n        \"topics\": [\n          \"enums\",\n          \"functional_programming\",\n          \"lists\",\n          \"pattern_matching\"\n        ]\n      },\n      {\n        \"slug\": \"affine-cipher\",\n        \"name\": \"Affine Cipher\",\n        \"uuid\": \"94fdd990-101b-4daf-8692-75085e6563f2\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 4,\n        \"topics\": [\n          \"cryptography\",\n          \"security\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"all-your-base\",\n        \"name\": \"All Your Base\",\n        \"uuid\": \"19d00436-f26a-47ad-b13e-128181dc09f3\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 4,\n        \"topics\": [\n          \"arrays\",\n          \"conditionals\",\n          \"exception_handling\",\n          \"integers\",\n          \"loops\",\n          \"math\"\n        ]\n      },\n      {\n        \"slug\": \"atbash-cipher\",\n        \"name\": \"Atbash Cipher\",\n        \"uuid\": \"b325401a-c8f0-49da-9f1a-a83318e780c9\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 4,\n        \"topics\": [\n          \"cryptography\",\n          \"security\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"diamond\",\n        \"name\": \"Diamond\",\n        \"uuid\": \"03c71e34-ecaf-47a4-9854-48600e1bf0d4\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 4,\n        \"topics\": [\n          \"arrays\",\n          \"lists\",\n          \"loops\",\n          \"strings\",\n          \"text_formatting\"\n        ]\n      },\n      {\n        \"slug\": \"grade-school\",\n        \"name\": \"Grade School\",\n        \"uuid\": \"62eb71dd-18ba-427f-a27a-86e993b4055a\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 4,\n        \"topics\": [\n          \"conditionals\",\n          \"lists\",\n          \"maps\",\n          \"sorting\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"isbn-verifier\",\n        \"name\": \"ISBN Verifier\",\n        \"uuid\": \"400d8014-9f75-43da-8a1c-93d95d91f4d2\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 4,\n        \"topics\": [\n          \"integers\",\n          \"loops\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"kindergarten-garden\",\n        \"name\": \"Kindergarten Garden\",\n        \"uuid\": \"1603e77a-0fbc-43ed-8200-b86a4219af8d\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 4,\n        \"topics\": [\n          \"arrays\",\n          \"enumerations\",\n          \"lists\",\n          \"logic\",\n          \"loops\",\n          \"pattern_recognition\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"largest-series-product\",\n        \"name\": \"Largest Series Product\",\n        \"uuid\": \"aa11e242-77b9-4ba7-97a2-d9b36e454a9d\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 4,\n        \"topics\": [\n          \"integers\",\n          \"loops\",\n          \"math\",\n          \"strings\",\n          \"type_conversion\"\n        ]\n      },\n      {\n        \"slug\": \"luhn\",\n        \"name\": \"Luhn\",\n        \"uuid\": \"3cf8a650-6a25-416e-a0af-036f41c11cca\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 4,\n        \"topics\": [\n          \"algorithms\",\n          \"booleans\",\n          \"loops\",\n          \"strings\",\n          \"type_conversion\"\n        ]\n      },\n      {\n        \"slug\": \"matrix\",\n        \"name\": \"Matrix\",\n        \"uuid\": \"46ab876c-cde2-4fa7-8970-b250ad8ccf74\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 4,\n        \"topics\": [\n          \"loops\",\n          \"strings\",\n          \"pattern_matching\",\n          \"type_conversion\",\n          \"transforming\"\n        ]\n      },\n      {\n        \"slug\": \"nth-prime\",\n        \"name\": \"Nth Prime\",\n        \"uuid\": \"6e2bbe8d-b6ab-4675-9c31-5b437cefd0c4\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 4,\n        \"topics\": [\n          \"arrays\",\n          \"exception_handling\",\n          \"integers\",\n          \"lists\",\n          \"loops\",\n          \"math\"\n        ]\n      },\n      {\n        \"slug\": \"robot-simulator\",\n        \"name\": \"Robot Simulator\",\n        \"uuid\": \"6e3b294b-16a3-4ebb-a78b-4bf7f6b96736\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 4,\n        \"topics\": [\n          \"classes\",\n          \"enumerations\",\n          \"logic\",\n          \"loops\"\n        ]\n      },\n      {\n        \"slug\": \"roman-numerals\",\n        \"name\": \"Roman Numerals\",\n        \"uuid\": \"da466ad5-6837-47d8-af39-2c0563d35a3c\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 4,\n        \"topics\": [\n          \"integers\",\n          \"logic\",\n          \"loops\",\n          \"maps\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"saddle-points\",\n        \"name\": \"Saddle Points\",\n        \"uuid\": \"371901d4-0728-4abd-8374-1905d7d70329\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 4,\n        \"topics\": [\n          \"arrays\",\n          \"conditionals\",\n          \"exception_handling\",\n          \"integers\",\n          \"loops\"\n        ]\n      },\n      {\n        \"slug\": \"sieve\",\n        \"name\": \"Sieve\",\n        \"uuid\": \"87ca4323-8a19-4529-962d-0f2ee63ebb2f\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 4,\n        \"topics\": [\n          \"algorithms\",\n          \"integers\",\n          \"lists\",\n          \"loops\",\n          \"math\"\n        ]\n      },\n      {\n        \"slug\": \"binary-search-tree\",\n        \"name\": \"Binary Search Tree\",\n        \"uuid\": \"12a9dd9f-28ed-4159-baf3-d28654cb8fa7\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 5,\n        \"topics\": [\n          \"arrays\",\n          \"generics\",\n          \"recursion\",\n          \"searching\"\n        ]\n      },\n      {\n        \"slug\": \"circular-buffer\",\n        \"name\": \"Circular Buffer\",\n        \"uuid\": \"e32c0edd-367c-4b66-b677-35e518d6831f\",\n        \"practices\": [],\n        \"prerequisites\": [\n          \"generics\"\n        ],\n        \"difficulty\": 5\n      },\n      {\n        \"slug\": \"custom-set\",\n        \"name\": \"Custom Set\",\n        \"uuid\": \"10b6cca2-6c36-4017-9464-32aa11c59f85\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 5,\n        \"topics\": [\n          \"object_oriented_programming\",\n          \"sets\",\n          \"varargs\"\n        ]\n      },\n      {\n        \"slug\": \"knapsack\",\n        \"name\": \"Knapsack\",\n        \"uuid\": \"1c2e8e65-1d1f-43ce-a626-70769f8bae5f\",\n        \"practices\": [],\n        \"prerequisites\": [\n          \"arrays\",\n          \"loops\",\n          \"lists\",\n          \"conditionals\"\n        ],\n        \"difficulty\": 5,\n        \"topics\": [\n          \"algorithms\",\n          \"logic\"\n        ]\n      },\n      {\n        \"slug\": \"matching-brackets\",\n        \"name\": \"Matching Brackets\",\n        \"uuid\": \"cbbbd7db-224f-45ca-a108-4dc6bc98e4a0\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 5,\n        \"topics\": [\n          \"stacks\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"meetup\",\n        \"name\": \"Meetup\",\n        \"uuid\": \"d617987e-64b8-4c21-89a9-66a932c4668d\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 5,\n        \"topics\": [\n          \"conditionals\",\n          \"dates\",\n          \"enumerations\",\n          \"loops\"\n        ]\n      },\n      {\n        \"slug\": \"pascals-triangle\",\n        \"name\": \"Pascal's Triangle\",\n        \"uuid\": \"67db30e4-b4d8-4224-b0f8-19a00af40387\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 5,\n        \"topics\": [\n          \"algorithms\",\n          \"arrays\",\n          \"exception_handling\",\n          \"integers\",\n          \"math\",\n          \"matrices\"\n        ]\n      },\n      {\n        \"slug\": \"pig-latin\",\n        \"name\": \"Pig Latin\",\n        \"uuid\": \"cb2ce8e5-f143-4423-a3bc-959f4222c186\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 5,\n        \"topics\": [\n          \"arrays\",\n          \"lists\",\n          \"strings\",\n          \"transforming\"\n        ]\n      },\n      {\n        \"slug\": \"robot-name\",\n        \"name\": \"Robot Name\",\n        \"uuid\": \"ce475b23-5dfc-4049-90c5-0c387926686f\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 5,\n        \"topics\": [\n          \"pattern_matching\",\n          \"randomness\",\n          \"regular_expressions\",\n          \"strings\",\n          \"text_formatting\"\n        ]\n      },\n      {\n        \"slug\": \"spiral-matrix\",\n        \"name\": \"Spiral Matrix\",\n        \"uuid\": \"e3407da5-0524-4565-b724-9778bba1033f\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 5,\n        \"topics\": [\n          \"arrays\",\n          \"integers\",\n          \"loops\",\n          \"matrices\"\n        ]\n      },\n      {\n        \"slug\": \"transpose\",\n        \"name\": \"Transpose\",\n        \"uuid\": \"045de074-eeb3-499e-9cf4-65b75d9988fc\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 5,\n        \"topics\": [\n          \"lists\",\n          \"loops\",\n          \"maps\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"bank-account\",\n        \"name\": \"Bank Account\",\n        \"uuid\": \"12e1d685-32be-4b2c-a40b-c68e5b60de1d\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 6,\n        \"topics\": [\n          \"concurrency\",\n          \"exception_handling\",\n          \"integers\"\n        ]\n      },\n      {\n        \"slug\": \"beer-song\",\n        \"name\": \"Beer Song\",\n        \"uuid\": \"34f0e7d0-29df-44e5-a7a7-4a12584af62e\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 6,\n        \"status\": \"deprecated\",\n        \"topics\": [\n          \"conditionals\",\n          \"loops\",\n          \"strings\",\n          \"text_formatting\",\n          \"variables\"\n        ]\n      },\n      {\n        \"slug\": \"bottle-song\",\n        \"name\": \"Bottle Song\",\n        \"uuid\": \"3e82fc4b-0863-43c1-86b5-70dce3c78711\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 6,\n        \"topics\": [\n          \"conditionals\",\n          \"loops\",\n          \"strings\",\n          \"text_formatting\",\n          \"variables\"\n        ]\n      },\n      {\n        \"slug\": \"bowling\",\n        \"name\": \"Bowling\",\n        \"uuid\": \"ae084405-48d7-43ea-9bc5-6c4ebae4c1ef\",\n        \"practices\": [],\n        \"prerequisites\": [\n          \"for-loops\",\n          \"arrays\"\n        ],\n        \"difficulty\": 6\n      },\n      {\n        \"slug\": \"flower-field\",\n        \"name\": \"Flower Field\",\n        \"uuid\": \"2bc77dfb-0e27-4beb-b8a1-20bed83ab6b7\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 6,\n        \"topics\": [\n          \"conditionals\",\n          \"games\",\n          \"integers\",\n          \"lists\",\n          \"matrices\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"linked-list\",\n        \"name\": \"Linked List\",\n        \"uuid\": \"fc977979-c8a4-44b6-a685-c8a32bd12bc3\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 6,\n        \"topics\": [\n          \"algorithms\",\n          \"generics\",\n          \"lists\"\n        ]\n      },\n      {\n        \"slug\": \"minesweeper\",\n        \"name\": \"Minesweeper\",\n        \"uuid\": \"8eb6f225-fa3d-4a33-b476-2cae45053c82\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 6,\n        \"topics\": [\n          \"conditionals\",\n          \"games\",\n          \"integers\",\n          \"lists\",\n          \"matrices\",\n          \"strings\"\n        ],\n        \"status\": \"deprecated\"\n      },\n      {\n        \"slug\": \"rail-fence-cipher\",\n        \"name\": \"Rail Fence Cipher\",\n        \"uuid\": \"49e730fb-7031-4de9-9bfd-b86564f20d8a\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 6,\n        \"topics\": [\n          \"cryptography\",\n          \"algorithms\",\n          \"strings\",\n          \"transforming\"\n        ]\n      },\n      {\n        \"slug\": \"say\",\n        \"name\": \"Say\",\n        \"uuid\": \"5607dae5-13aa-4cd4-8b4c-d270516182d7\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 6,\n        \"topics\": [\n          \"strings\",\n          \"transforming\"\n        ]\n      },\n      {\n        \"slug\": \"wordy\",\n        \"name\": \"Wordy\",\n        \"uuid\": \"3c7a3c6b-8dc7-4e5a-ba72-e1a4bffb0bc4\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 6,\n        \"topics\": [\n          \"loops\",\n          \"pattern_matching\",\n          \"strings\",\n          \"recursion\"\n        ]\n      },\n      {\n        \"slug\": \"dominoes\",\n        \"name\": \"Dominoes\",\n        \"uuid\": \"c52c4b61-dca2-4b73-87b6-b4f2f63d9fdb\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 7,\n        \"topics\": [\n          \"algorithms\",\n          \"exception_handling\",\n          \"games\",\n          \"lists\"\n        ]\n      },\n      {\n        \"slug\": \"change\",\n        \"name\": \"Change\",\n        \"uuid\": \"0d69c1cd-f190-4b3b-8472-bf78c02acbc5\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 8,\n        \"topics\": [\n          \"algorithms\",\n          \"exception_handling\",\n          \"integers\",\n          \"lists\"\n        ]\n      },\n      {\n        \"slug\": \"complex-numbers\",\n        \"name\": \"Complex Numbers\",\n        \"uuid\": \"83dec96f-9cdf-4b9b-abc4-cbd2066d919a\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 8,\n        \"topics\": [\n          \"floating_point_numbers\",\n          \"math\"\n        ]\n      },\n      {\n        \"slug\": \"diffie-hellman\",\n        \"name\": \"Diffie-Hellman\",\n        \"uuid\": \"33d64c7c-292e-4221-aed8-ac411a9d490d\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 8,\n        \"topics\": [\n          \"cryptography\",\n          \"randomness\",\n          \"algorithms\",\n          \"integers\"\n        ]\n      },\n      {\n        \"slug\": \"forth\",\n        \"name\": \"Forth\",\n        \"uuid\": \"81d48ea4-0e88-45f2-839f-fe13e2059e92\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 8,\n        \"topics\": [\n          \"pattern_matching\",\n          \"integers\"\n        ]\n      },\n      {\n        \"slug\": \"list-ops\",\n        \"name\": \"List Ops\",\n        \"uuid\": \"34f1d5bf-f31f-415e-9905-4d48e6205d28\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 8,\n        \"topics\": [\n          \"filtering\",\n          \"functional_programming\",\n          \"generics\",\n          \"lists\",\n          \"loops\"\n        ]\n      },\n      {\n        \"slug\": \"simple-cipher\",\n        \"name\": \"Simple Cipher\",\n        \"uuid\": \"e23b06de-bd91-482f-9783-b0334b75b489\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 8,\n        \"topics\": [\n          \"cryptography\",\n          \"exception_handling\",\n          \"randomness\",\n          \"security\",\n          \"strings\"\n        ]\n      },\n      {\n        \"slug\": \"zebra-puzzle\",\n        \"name\": \"Zebra Puzzle\",\n        \"uuid\": \"fe876a9b-2991-4624-a6fe-4311cb78f068\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 9,\n        \"topics\": [\n          \"algorithms\",\n          \"arrays\",\n          \"conditionals\",\n          \"games\"\n        ]\n      },\n      {\n        \"slug\": \"react\",\n        \"name\": \"React\",\n        \"uuid\": \"240788cd-afa5-4fd6-8df0-a158239c0610\",\n        \"practices\": [],\n        \"prerequisites\": [],\n        \"difficulty\": 10,\n        \"topics\": [\n          \"generics\",\n          \"functional_programming\",\n          \"classes\",\n          \"reactive_programming\"\n        ]\n      }\n    ]\n  },\n  \"concepts\": [\n    {\n      \"uuid\": \"72e47dcb-dccf-44a5-ab91-8773c2aec5bd\",\n      \"slug\": \"basics\",\n      \"name\": \"Basics\"\n    },\n    {\n      \"uuid\": \"53e0b729-810e-4042-9477-8c8d05a7b302\",\n      \"slug\": \"booleans\",\n      \"name\": \"Booleans\"\n    },\n    {\n      \"uuid\": \"157bbe3b-e4f5-41f7-8e0e-e2f57d526617\",\n      \"slug\": \"strings\",\n      \"name\": \"Strings\"\n    },\n    {\n      \"uuid\": \"168827c0-4867-449a-ad22-611c87314c48\",\n      \"slug\": \"conditionals\",\n      \"name\": \"Conditionals\"\n    },\n    {\n      \"uuid\": \"660e1acd-3072-4bbc-ae44-bbc204da5eab\",\n      \"slug\": \"chars\",\n      \"name\": \"Chars\"\n    },\n    {\n      \"uuid\": \"98809a4c-ca3e-4504-b723-aff13bfae850\",\n      \"slug\": \"nullability\",\n      \"name\": \"Nullability\"\n    },\n    {\n      \"uuid\": \"1050abed-4271-4519-a44c-a0ca121c7de2\",\n      \"slug\": \"bitwise-operations\",\n      \"name\": \"Bitwise Operations\"\n    }\n  ],\n  \"key_features\": [\n    {\n      \"title\": \"Pragmatic\",\n      \"content\": \"Kotlin is trying hard to be a modern language with great tooling support.\",\n      \"icon\": \"powerful\"\n    },\n    {\n      \"title\": \"Statically Typed\",\n      \"content\": \"Strong type-safety and null-safety features for building robust software.\",\n      \"icon\": \"immutable\"\n    },\n    {\n      \"title\": \"Multi-Paradigm\",\n      \"content\": \"Kotlin support both functional and mainstream OOP programming principles.\",\n      \"icon\": \"multi-paradigm\"\n    },\n    {\n      \"title\": \"Platform Independent\",\n      \"content\": \"Develop for Android, iOS, JVM, Node.js, browser and many native targets.\",\n      \"icon\": \"cross-platform\"\n    },\n    {\n      \"title\": \"Garbage collected\",\n      \"content\": \"Kotlin (as a modern generic-purpose language) does memory management for you.\",\n      \"icon\": \"garbage-collected\"\n    },\n    {\n      \"title\": \"Open-Source\",\n      \"content\": \"Kotlin is fully open-source. Submit patches or suggest language improvements.\",\n      \"icon\": \"community\"\n    }\n  ],\n  \"tags\": [\n    \"execution_mode/compiled\",\n    \"paradigm/functional\",\n    \"paradigm/imperative\",\n    \"paradigm/object_oriented\",\n    \"platform/android\",\n    \"platform/linux\",\n    \"platform/mac\",\n    \"platform/web\",\n    \"platform/windows\",\n    \"runtime/jvm\",\n    \"typing/static\",\n    \"typing/strong\",\n    \"used_for/backends\",\n    \"used_for/cross_platform_development\",\n    \"used_for/games\",\n    \"used_for/mobile\"\n  ]\n}\n"
  },
  {
    "path": "docs/ABOUT.md",
    "content": "# About\n\nKotlin was designed and developed by JetBrains, the company behind IntelliJ. \r\nIt is a language that runs on the JVM which can target versions 6+ (including the [Android platform](https://blog.jetbrains.com/kotlin/2017/05/kotlin-on-android-now-official/)).\r\nJetBrains wanted to use a statically typed language which can remove Java boilerplate code, provide modern functional paradigms, and had seamless two-way Java interoperability with their existing codebase. \r\nThe JVM already had alternate languages like Groovy and Scala but neither fit the bill with their desired criteria, so they built Kotlin.\r\n\r\nKotlin syntax is similar to Scala and Swift but pulls in the best-of-breed features from other languages such as\r\nC# and Groovy. \r\nKotlin took a pragmatic approach at features included in the language by only providing functionality that has\r\nbeen proven to be useful for developers. \r\nWith this decision they implemented a subset of features of Scala with the intent that it will provide more maintainable code with an easier learning curve for developers looking for a \"better Java\".\r\n\r\nJetBrains has a dedicated team of developers working on Kotlin with the codebase available on [Github](https://github.com/JetBrains/kotlin).\r\n"
  },
  {
    "path": "docs/INSTALLATION.md",
    "content": "# Installing Kotlin\n\nIn addition to the exercism CLI and your favorite text editor, practicing with Exercism exercises in Kotlin requires\n\n* the **Java Development Kit** (JDK) — Kotlin compiles to Java bytecodes; you need to install the JDK which includes both a Java Runtime *and* development tools (most notably, the Java compiler); and\n* **Gradle** — a build tool specifically for JVM-based projects and supports Kotlin.\n\nChoose your operating system:\n\n* [Windows](#h-windows)\n* [macOS](#h-macos)\n* [Linux](#h-linux)\n\n... or ...\n* if you prefer to not use a package manager, you can [install manually](#h-install-manually).\n\nOptionally, you can also use a [Java IDE](#h-java-ides).\n\n----\n\n## Windows\n\nOpen an administrative command prompt.  (If you need assistance opening an administrative prompt, see [open an elevated prompt in Windows 8+](http://www.howtogeek.com/194041/how-to-open-the-command-prompt-as-administrator-in-windows-8.1/) (or [Windows 7](http://www.howtogeek.com/howto/windows-vista/run-a-command-as-administrator-from-the-windows-vista-run-box/)).\n\n1. If you have not installed Chocolatey, do so now:\n\n      ```batchfile\n        C:\\Windows\\system32> @powershell -NoProfile -ExecutionPolicy unrestricted -Command \"iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))\" && SET PATH=%PATH%;%ALLUSERSPROFILE%\\chocolatey\\bin\n      ```\n\n2.  Install the JDK:\n\n       ```batchfile\n        C:\\Windows\\system32> choco install openjdk11\n        ...\n        C:\\Windows\\system32> refreshenv\n        ...\n       ```\n\nWe recommend closing the administrative command prompt and opening a new command prompt -- you do not require administrator privileges to practice Exercism exercises.\n\nYou now are ready to get started with the Kotlin track of Exercism!\n\nTo get started, see \"[Running the Tests](https://exercism.org/docs/tracks/kotlin/tests)\".\n\n----\n\n## macOS\n\nBelow are instructions for install using the most common method - using Homebrew.  If you'd rather, you can also [install on macOS without Homebrew](#h-installing-on-macos-without-homebrew).\n\n### Installing\n\n1. If you haven't installed [Homebrew](http://brew.sh), yet, do so now:\n\n      ```sh\n        $ /usr/bin/ruby -e \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\"\n      ```\n\n2. Tap the [Homebrew Cask](https://caskroom.github.io/) — this allows us to install pre-built binaries like the JDK.\n\n      ```\n        $ brew tap adoptopenjdk/openjdk\n      ```\n\n3.  Install the JDK:\n\n       ```\n        $ brew install --cask adoptopenjdk11\n       ```\n\nYou now are ready to get started with the Kotlin track of Exercism!\n\nTo get started, see \"[Running the Tests](https://exercism.org/docs/tracks/kotlin/tests)\".\n\n----\n\n## Linux\n\nBelow are instructions for install using the package manager of your distro.  If you'd rather, you can also [install on Linux without a package manager](#h-installing-on-linux-without-a-package-manager).\n\n* [Debian](#h-debian)\n* [Other Linux distributions](#h-other-linux-distributions)\n\n### Debian\n\nIf you are using Debian or its derivatives (like Ubuntu or Linux Mint), use APT:\n\n*(verified on: Ubuntu 14, 16 and 18)*\n\n1. Install the JDK:\n\n      ```sh\n        $ sudo apt-get update\n        $ sudo apt-get install software-properties-common\n        $ sudo add-apt-repository ppa:openjdk-r/ppa\n        $ sudo apt-get update\n        $ sudo apt-get install openjdk-11-jdk\n      ```\n\n\nYou now are ready to get started with the Kotlin track of Exercism!\n\nTo get started, see \"[Running the Tests](https://exercism.org/docs/tracks/kotlin/tests)\".\n\n----\n\n### Other Linux distributions\n\nThere are a lot of ways to install Jdk 11, but one of the easiest ways is to use SDKMAN, \nwhich lets you install OpenJdk11 with ease. Use the following steps:\n\n1. Install SDKMAN:\n    ```sh\n    $ curl -s \"https://get.sdkman.io\" | bash\n    ``` \n    (if that doesn't work, take a look at the instructions found here: https://sdkman.io/install )\n1. Install openjdk11:\n    ```\n    $ sdk install java 11.0.2-open\n    ``` \n\nYou now are ready to get started with the Kotlin track of Exercism!\n\nTo get started, see \"[Running the Tests](https://exercism.org/docs/tracks/kotlin/tests)\".\n\n----\n\n## Install Manually\n\n* [Installing on Windows manually](#h-installing-on-windows-manually)\n* [Installing on macOS without Homebrew](#h-installing-on-macos-without-homebrew)\n* [Installing on Linux without a package manager](#h-installing-on-linux-without-a-package-manager)\n\n----\n\n### Installing on Windows manually\n\n*NOTE: these instructions are intended for experienced Windows users.  If you don't already know how to set environment variables or feel comfortable managing the directory structure, we highly recommend you use the Chocolatey-based install, [above](#h-windows).*\n\n1. Install the JDK:\n   1. Download \"**OpenJDK 11 (LTS)**\" from [AdoptOpenJDK](https://adoptopenjdk.net/releases.html?variant=openjdk11#x64_win) (choose **\"Install JDK\"**).\n   -  Run the installer, using all the defaults.\n\nYou now are ready to get started with the Kotlin track of Exercism!\n\nTo get started, see \"[Running the Tests](https://exercism.org/docs/tracks/kotlin/tests)\".\n\n----\n\n### Installing on macOS without Homebrew\n\n*NOTE: these instructions are intended for experienced macOS users.  Unless you specifically do not want to use a package manager, we highly recommend using the Homebrew-based installation instructions, [above](#h-macos).*\n\n1. Install the JDK:\n   1. Download \"**OpenJDK 11 (LTS)**\" from [AdoptOpenJDK](https://adoptopenjdk.net/releases.html?variant=openjdk11#x64_mac) (choose **\"Install JDK\"**).\n   2. Run the installer, using all the defaults.\n      \nYou now are ready to get started with the Kotlin track of Exercism!\n\nTo get started, see \"[Running the Tests](https://exercism.org/docs/tracks/kotlin/tests)\".\n\n----\n\n### Installing on Linux without a package manager\n\n*NOTE: these instructions are intended for experienced Linux users.  Unless you specifically do not want to use a package manager, we highly recommend using the the installation instructions, [above](#h-linux).*\n\n1. Install the JDK:\n   1. Choose your distribution and download \"**OpenJDK 11 (LTS)**\" from [AdoptOpenJDK](https://adoptopenjdk.net/releases.html?variant=openjdk11) (choose **\"Install JDK\"**).\n   2. Run the installer, using all the defaults.\n\nYou now are ready to get started with the Kotlin track of Exercism!\n\nTo get started, see \"[Running the Tests](https://exercism.org/docs/tracks/kotlin/tests)\".\n\n----\n\n## Java IDEs\n\nThere are many Java IDEs available.  The three most popular are:\n\n* [IntelliJ IDEA](https://www.jetbrains.com/idea/download/) (download the \"Community\" edition)\n  - from the authors of Kotlin, this IDE provides the best support for the language.\n- [Eclipse](https://www.eclipse.org/downloads/)\n- [NetBeans](https://netbeans.org/downloads/) (download the \"Java SE\" bundle)\n\nand there are [others](https://en.wikibooks.org/wiki/Java_Programming/Java_IDEs).\n\n"
  },
  {
    "path": "docs/LEARNING.md",
    "content": "# Recommended learning resources\n\n* [Get started with Kotlin](https://kotlinlang.org/docs/getting-started.html)\n* [Kotlin Documentation](https://kotlinlang.org/docs/home.html)\n  * [Kotlin Idioms](https://kotlinlang.org/docs/idioms.html)\n* [Kotlin Tutorial Videos](https://kotlinlang.org/docs/videos.html)\n* [Kotlin examples](https://play.kotlinlang.org/byExample/overview)\n* [Kotlin on Stack Overflow](https://stackoverflow.com/questions/tagged/kotlin)\n"
  },
  {
    "path": "docs/RESOURCES.md",
    "content": "# Recommended resources\n\n* [Kotlin Documentation](https://kotlinlang.org/docs/reference/)\n* [Kotlin Forums](https://discuss.kotlinlang.org/)\n* [Kotlin Slack Channel](http://kotlinlang.slack.com/): [get invite here](http://slack.kotlinlang.org/)\n* [Stack Overflow](https://stackoverflow.com/questions/tagged/kotlin)\n* [Reddit Channel](https://www.reddit.com/r/kotlin)\n* [X (formerly Twitter)](https://x.com/kotlin)\n\n"
  },
  {
    "path": "docs/SNIPPET.txt",
    "content": "fun getGreeting(): String {\n    return \"Hello, World!\"\n}\n"
  },
  {
    "path": "docs/TESTS.md",
    "content": "# Tests\n\n## Running the Tests\n\n1. Get an exercise:\n\n    ```bash\n    $ exercism download -track=kotlin --exercise=hello-world\n    ```\n\n2. Change directory into the exercise:\n\n    ```bash\n    $ cd <path_to_exercise_directory>\n    ```\n\n3. Run the tests:\n\n    ```bash\n    $ ./gradlew test\n    ```\n\nOn most exercises, only the first test is run by default.  \nThe other tests are annotated with `@Ignore` to skip them.  \nAs you solve each test, remove the `@Ignore` from the next one to progress.\n\nThis is common practice in test-driven development (or TDD for short).\nIt is used to ensure that you are working on one problem at a time.\n\n---\nGood luck! Have fun!\n\nIf you get stuck at any point, feel free to reach out for help on the [forum](https://exercism.org/r/forum) or our `#get-help` channel on our [Discord server](https://exercism.org/r/discord)."
  },
  {
    "path": "docs/config.json",
    "content": "{\n  \"docs\": [\n    {\n      \"uuid\": \"91fa3615-3f2d-44fe-a060-93dac297583c\",\n      \"slug\": \"installation\",\n      \"path\": \"docs/INSTALLATION.md\",\n      \"title\": \"Installing Kotlin locally\",\n      \"blurb\": \"Learn how to install Kotlin locally to solve Exercism's exercises on your own machine\"\n    },\n    {\n      \"uuid\": \"015670c8-aded-4ba5-9824-454e928b8d37\",\n      \"slug\": \"learning\",\n      \"path\": \"docs/LEARNING.md\",\n      \"title\": \"How to learn Kotlin\",\n      \"blurb\": \"An overview of how to get started from scratch with Kotlin\"\n    },\n    {\n      \"uuid\": \"f2a23a48-b160-4925-98c6-8844ab63b931\",\n      \"slug\": \"tests\",\n      \"path\": \"docs/TESTS.md\",\n      \"title\": \"Testing on the Kotlin track\",\n      \"blurb\": \"Learn how to test your Kotlin exercises on Exercism\"\n    },\n    {\n      \"uuid\": \"336b6d0a-43a1-44d4-b1ac-0320aed1baa7\",\n      \"slug\": \"resources\",\n      \"path\": \"docs/RESOURCES.md\",\n      \"title\": \"Useful Kotlin resources\",\n      \"blurb\": \"A collection of useful resources to help you master Kotlin\"\n    }\n  ]\n}\n"
  },
  {
    "path": "exercises/build.gradle.kts",
    "content": "import org.jetbrains.kotlin.gradle.tasks.KotlinCompile\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nproject(\":practice\").subprojects {\n    afterEvaluate {\n        configurations {\n            create(\"starterSourceCompile\").extendsFrom(getByName(\"implementation\"))\n            create(\"starterSourceRuntime\").extendsFrom(getByName(\"runtimeOnly\"))\n\n            create(\"exerciseTestsCompile\").extendsFrom(getByName(\"testImplementation\"))\n            create(\"exerciseTestsRuntime\").extendsFrom(getByName(\"testRuntimeOnly\"))\n        }\n\n        kotlin {\n            sourceSets {\n                main {\n                    kotlin.setSrcDirs(listOf(file(\".meta/src/reference/kotlin\")))\n                }\n                test {\n                    kotlin.setSrcDirs(listOf(\"build/gen/test/kotlin\"))\n                }\n                val starterSource by creating {\n                    kotlin.setSrcDirs(listOf(\"src/main/kotlin\"))\n                }\n                val exerciseTests by creating {\n                    kotlin.setSrcDirs(listOf(\"src/test/kotlin\"))\n                }\n            }\n        }\n\n        tasks {\n            val copyTestsFilteringIgnores by creating(Copy::class) {\n                from(\"src/test/kotlin\")\n                into(\"build/gen/test/kotlin\")\n                filter { line -> if (line.contains(\"@Ignore\")) \"\" else line }\n            }\n\n            compileKotlin {\n                doFirst {\n                    println(\"  (source = ${source.asPath})\")\n                }\n            }\n            compileTestKotlin {\n                dependsOn(copyTestsFilteringIgnores)\n\n                doFirst {\n                    println(\"  (test source = ${source.asPath})\")\n                }\n            }\n\n            /*val compileStarterSourceKotlin by existing(KotlinCompile::class) {\n                println(\"  (source = ${source.asPath})\")\n            }*/\n\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/concept/annalyns-infiltration/.docs/hints.md",
    "content": "# Hints\n\n## General\n\n- There are three [boolean operators][reference] to work with boolean values.\n- Multiple operators can be combined in a single expression.\n\n## 1. Check if a fast attack can be made\n\n- The [boolean operators][reference] can also be applied to boolean parameters.\n\n[reference]: https://kotlinlang.org/docs/reference/basic-types.html#booleans\n"
  },
  {
    "path": "exercises/concept/annalyns-infiltration/.docs/instructions.md",
    "content": "# Instructions\n\nIn this exercise, you'll be implementing the quest logic for a new RPG game a friend is developing. The game's main character is Annalyn, a brave girl with a fierce and loyal pet dog. Unfortunately, disaster strikes, as her best friend was kidnapped while searching for berries in the forest. Annalyn will try to find and free her best friend, optionally taking her dog with her on this quest.\n\nAfter some time spent following her best friend's trail, she finds the camp in which her best friend is imprisoned. It turns out there are two kidnappers: a mighty knight and a cunning archer.\n\nHaving found the kidnappers, Annalyn considers which of the following actions she can engage in:\n\n- Fast attack: a fast attack can be made if the knight is sleeping, as it takes time for him to get his armor on, so he will be vulnerable.\n- Spy: the group can be spied upon if at least one of them is awake. Otherwise, spying is a waste of time.\n- Signal prisoner: the prisoner can be signalled using bird sounds if the prisoner is awake and the archer is sleeping, as archers are trained in bird signaling so they could intercept the message.\n- _Free prisoner_: Annalyn can try sneaking into the camp to free the prisoner.\n  This is a risky thing to do and can only succeed in one of two ways:\n  - If Annalyn has her pet dog with her she can rescue the prisoner if the archer is asleep.\n    The knight is scared of the dog and the archer will not have time to get ready before Annalyn and the prisoner can escape.\n  - If Annalyn does not have her dog then she and the prisoner must be very sneaky!\n    Annalyn can free the prisoner if the prisoner is awake and the knight and archer are both sleeping, but if the prisoner is sleeping they can't be rescued: the prisoner would be startled by Annalyn's sudden appearance and wake up the knight and archer.\n\nYou have four tasks: to implement the logic for determining if the above actions are available based on the state of the three characters found in the forest and whether Annalyn's pet dog is present or not.\n\n## 1. Check if a fast attack can be made\n\nImplement the `canFastAttack()` method that takes a boolean value that indicates if the knight is awake. This method returns `true` if a fast attack can be made based on the state of the knight. Otherwise, returns `false`:\n\n```kotlin\nval knightIsAwake = true\n\ncanFastAttack(knightIsAwake)\n// => false\n```\n\n## 2. Check if the group can be spied upon\n\nImplement the `canSpy()` method that takes three boolean values, indicating if the knight, archer and the prisoner, respectively, are awake. The method returns `true` if the group can be spied upon, based on the state of the three characters. Otherwise, returns `false`:\n\n```kotlin\nval knightIsAwake = false\nval archerIsAwake = true\nval prisonerIsAwake = false\n\ncanSpy(knightIsAwake, archerIsAwake, prisonerIsAwake)\n// => true\n```\n\n## 3. Check if the prisoner can be signalled\n\nImplement the `canSignalPrisoner()` method that takes two boolean values, indicating if the archer and the prisoner, respectively, are awake. The method returns `true` if the prisoner can be signalled, based on the state of the two characters. Otherwise, returns `false`:\n\n```kotlin\nval archerIsAwake = false\nval prisonerIsAwake = true\n\ncanSignalPrisoner(archerIsAwake, prisonerIsAwake)\n// => true\n```\n\n## 4. Check if the prisoner can be freed\n\nImplement the `canFreePrisoner()` method that takes four boolean values. The first three parameters indicate if the knight, archer and the prisoner, respectively, are awake. The last parameter indicates if Annalyn's pet dog is present. The method returns `true` if the prisoner can be freed based on the state of the three characters and Annalyn's pet dog presence. Otherwise, it returns `false`:\n\n```kotlin\nval knightIsAwake = false\nval archerIsAwake = true\nval prisonerIsAwake = false\nval petDogIsPresent = false\n\ncanFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent)\n// => false\n```\n"
  },
  {
    "path": "exercises/concept/annalyns-infiltration/.docs/introduction.md",
    "content": "# Introduction\n\nBooleans in Kotlin are represented by the `Boolean` type, which values can be either `true` or `false`.\n\nKotlin supports three built-in [boolean operators][reference]: `!` (negation aka NOT), `&&` (lazy conjunction aka AND), and `||` (lazy disjunction aka OR). The `&&` and `||` operators use _short-circuit evaluation_, which means that the right-hand side of the operator is only evaluated when needed.\n"
  },
  {
    "path": "exercises/concept/annalyns-infiltration/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"dector\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/AnnalynsInfiltration.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/AnnalynsInfiltrationTest.kt\"\n    ],\n    \"exemplar\": [\n      \".meta/src/reference/kotlin/AnnalynsInfiltration.kt\"\n    ]\n  },\n  \"forked_from\": [\n    \"fsharp/annalyns-infiltration\"\n  ],\n  \"blurb\": \"Learn about booleans while helping Annalyn rescue her friend.\"\n}\n"
  },
  {
    "path": "exercises/concept/annalyns-infiltration/.meta/design.md",
    "content": "# Design\n\n## Learning objectives\n\n- Know of the existence of the `Boolean` type and its two values.\n- Know about boolean operators and how to build logical expressions with them.\n- Know of the boolean operator precedence rules.\n\n## Out of scope\n\n- Pattern matching on booleans.\n\n## Concepts\n\n- `booleans`: know of the existence of the `Boolean` type and its two values; know about boolean operators and how to build logical expressions with them; know of the boolean operator precedence rules.\n\n## Prerequisites\n\nThis exercise's prerequisites Concepts are:\n\n- `basics`: know how to define methods.\n"
  },
  {
    "path": "exercises/concept/annalyns-infiltration/.meta/src/reference/kotlin/AnnalynsInfiltration.kt",
    "content": "fun canFastAttack(knightIsAwake: Boolean): Boolean =\n    !knightIsAwake\n\nfun canSpy(\n    knightIsAwake: Boolean,\n    archerIsAwake: Boolean,\n    prisonerIsAwake: Boolean\n): Boolean =\n    knightIsAwake || archerIsAwake || prisonerIsAwake\n\nfun canSignalPrisoner(archerIsAwake: Boolean, prisonerIsAwake: Boolean): Boolean =\n    !archerIsAwake && prisonerIsAwake\n\nfun canFreePrisoner(\n    knightIsAwake: Boolean,\n    archerIsAwake: Boolean,\n    prisonerIsAwake: Boolean,\n    petDogIsPresent: Boolean\n): Boolean =\n    !knightIsAwake &&\n        !archerIsAwake &&\n        prisonerIsAwake || !archerIsAwake &&\n        petDogIsPresent\n"
  },
  {
    "path": "exercises/concept/annalyns-infiltration/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/concept/annalyns-infiltration/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/concept/annalyns-infiltration/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/concept/annalyns-infiltration/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/concept/annalyns-infiltration/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/concept/annalyns-infiltration/src/main/kotlin/AnnalynsInfiltration.kt",
    "content": "fun canFastAttack(knightIsAwake: Boolean): Boolean {\n    TODO(\"Please implement the canFastAttack() method\")\n}\n\nfun canSpy(\n    knightIsAwake: Boolean,\n    archerIsAwake: Boolean,\n    prisonerIsAwake: Boolean\n): Boolean {\n    TODO(\"Please implement the canSpy() method\")\n}\n\nfun canSignalPrisoner(archerIsAwake: Boolean, prisonerIsAwake: Boolean): Boolean {\n    TODO(\"Please implement the canSignalPrisoner() method\")\n}\n\nfun canFreePrisoner(\n    knightIsAwake: Boolean,\n    archerIsAwake: Boolean,\n    prisonerIsAwake: Boolean,\n    petDogIsPresent: Boolean\n): Boolean {\n    TODO(\"Please implement the canFreePrisoner() method\")\n}\n"
  },
  {
    "path": "exercises/concept/annalyns-infiltration/src/test/kotlin/AnnalynsInfiltrationTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertFalse\nimport kotlin.test.assertTrue\n\n\nclass AnnalynsInfiltrationTest {\n\n    @Test\n    fun `Cannot execute fast attack if knight is awake`() {\n        val knightIsAwake = true\n\n        assertFalse(canFastAttack(knightIsAwake))\n    }\n\n    @Test\n    fun `Can execute fast attack if knight is sleeping`() {\n        val knightIsAwake = false\n\n        assertTrue(canFastAttack(knightIsAwake))\n    }\n\n    @Test\n    fun `Cannot spy if everyone is sleeping`() {\n        val knightIsAwake = false\n        val archerIsAwake = false\n        val prisonerIsAwake = false\n\n        assertFalse(canSpy(knightIsAwake, archerIsAwake, prisonerIsAwake))\n    }\n\n    @Test\n    fun `Can spy if everyone but knight is sleeping`() {\n        val knightIsAwake = true\n        val archerIsAwake = false\n        val prisonerIsAwake = false\n        assertTrue(canSpy(knightIsAwake, archerIsAwake, prisonerIsAwake))\n    }\n\n    @Test\n    fun `Can spy if everyone but archer is sleeping`() {\n        val knightIsAwake = false\n        val archerIsAwake = true\n        val prisonerIsAwake = false\n\n        assertTrue(canSpy(knightIsAwake, archerIsAwake, prisonerIsAwake))\n    }\n\n    @Test\n    fun `Can spy if everyone but prisoner is sleeping`() {\n        val knightIsAwake = false\n        val archerIsAwake = false\n        val prisonerIsAwake = true\n\n        assertTrue(canSpy(knightIsAwake, archerIsAwake, prisonerIsAwake))\n    }\n\n    @Test\n    fun `Can spy if only knight is sleeping`() {\n        val knightIsAwake = false\n        val archerIsAwake = true\n        val prisonerIsAwake = true\n\n        assertTrue(canSpy(knightIsAwake, archerIsAwake, prisonerIsAwake))\n    }\n\n    @Test\n    fun `Can spy if only archer is sleeping`() {\n        val knightIsAwake = true\n        val archerIsAwake = false\n        val prisonerIsAwake = true\n\n        assertTrue(canSpy(knightIsAwake, archerIsAwake, prisonerIsAwake))\n    }\n\n    @Test\n    fun `Can spy if only prisoner is sleeping`() {\n        val knightIsAwake = true\n        val archerIsAwake = true\n        val prisonerIsAwake = false\n\n        assertTrue(canSpy(knightIsAwake, archerIsAwake, prisonerIsAwake))\n    }\n\n    @Test\n    fun `Can spy if everyone is awake`() {\n        val knightIsAwake = true\n        val archerIsAwake = true\n        val prisonerIsAwake = true\n\n        assertTrue(canSpy(knightIsAwake, archerIsAwake, prisonerIsAwake))\n    }\n\n    @Test\n    fun `Can signal prisoner ifarcher is sleeping and prisoner is awake`() {\n        val archerIsAwake = false\n        val prisonerIsAwake = true\n\n        assertTrue(canSignalPrisoner(archerIsAwake, prisonerIsAwake))\n    }\n\n    @Test\n    fun `Cannot signal prisoner ifarcher is awake and prisoner is sleeping`() {\n        val archerIsAwake = true\n        val prisonerIsAwake = false\n\n        assertFalse(canSignalPrisoner(archerIsAwake, prisonerIsAwake))\n    }\n\n    @Test\n    fun `Cannot signal prisoner ifarcher and prisoner are both sleeping`() {\n        val archerIsAwake = false\n        val prisonerIsAwake = false\n\n        assertFalse(canSignalPrisoner(archerIsAwake, prisonerIsAwake))\n    }\n\n    @Test\n    fun `Cannot signal prisoner ifarcher and prisoner are both awake`() {\n        val archerIsAwake = true\n        val prisonerIsAwake = true\n\n        assertFalse(canSignalPrisoner(archerIsAwake, prisonerIsAwake))\n    }\n\n    @Test\n    fun `Cannot release prisoner if everyone is awake and pet dog is present`() {\n        val knightIsAwake = true\n        val archerIsAwake = true\n        val prisonerIsAwake = true\n        val petDogIsPresent = true\n\n        assertFalse(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n\n    @Test\n    fun `Cannot release prisoner if everyone is awake and pet dog is absent`() {\n        val knightIsAwake = true\n        val archerIsAwake = true\n        val prisonerIsAwake = true\n        val petDogIsPresent = false\n\n        assertFalse(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n\n    @Test\n    fun `Can release prisoner if everyone is asleep and pet dog is present`() {\n        val knightIsAwake = false\n        val archerIsAwake = false\n        val prisonerIsAwake = false\n        val petDogIsPresent = true\n\n        assertTrue(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n\n    @Test\n    fun `Cannot release prisoner if everyone is asleep and pet dog is absent`() {\n        val knightIsAwake = false\n        val archerIsAwake = false\n        val prisonerIsAwake = false\n        val petDogIsPresent = false\n\n        assertFalse(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n\n    @Test\n    fun `Can release prisoner if only prisoner is awake and pet dog is present`() {\n        val knightIsAwake = false\n        val archerIsAwake = false\n        val prisonerIsAwake = true\n        val petDogIsPresent = true\n\n        assertTrue(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n\n    @Test\n    fun `Can release prisoner if only prisoner is awake and pet dog is absent`() {\n        val knightIsAwake = false\n        val archerIsAwake = false\n        val prisonerIsAwake = true\n        val petDogIsPresent = false\n\n        assertTrue(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n\n    @Test\n    fun `Cannot release prisoner if only archer is awake and pet dog is present`() {\n        val knightIsAwake = false\n        val archerIsAwake = true\n        val prisonerIsAwake = false\n        val petDogIsPresent = true\n\n        assertFalse(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n\n    @Test\n    fun `Cannot release prisoner if only archer is awake and pet dog is absent`() {\n        val knightIsAwake = false\n        val archerIsAwake = true\n        val prisonerIsAwake = false\n        val petDogIsPresent = false\n\n        assertFalse(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n\n    @Test\n    fun `Can release prisoner if only knight is awake and pet dog is present`() {\n        val knightIsAwake = true\n        val archerIsAwake = false\n        val prisonerIsAwake = false\n        val petDogIsPresent = true\n\n        assertTrue(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n\n    @Test\n    fun `Cannot release prisoner if only knight is awake and pet dog is absent`() {\n        val knightIsAwake = true\n        val archerIsAwake = false\n        val prisonerIsAwake = false\n        val petDogIsPresent = false\n\n        assertFalse(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n\n    @Test\n    fun `Cannot release prisoner if only knight is asleep and pet dog is present`() {\n        val knightIsAwake = false\n        val archerIsAwake = true\n        val prisonerIsAwake = true\n        val petDogIsPresent = true\n\n        assertFalse(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n\n    @Test\n    fun `Cannot release prisoner if only knight is asleep and pet dog is absent`() {\n        val knightIsAwake = false\n        val archerIsAwake = true\n        val prisonerIsAwake = true\n        val petDogIsPresent = false\n\n        assertFalse(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n\n    @Test\n    fun `Can release prisoner if only archer is asleep and pet dog is present`() {\n        val knightIsAwake = true\n        val archerIsAwake = false\n        val prisonerIsAwake = true\n        val petDogIsPresent = true\n\n        assertTrue(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n\n    @Test\n    fun `Cannot release prisoner if only archer is asleep and pet dog is absent`() {\n        val knightIsAwake = true\n        val archerIsAwake = false\n        val prisonerIsAwake = true\n        val petDogIsPresent = false\n\n        assertFalse(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n\n    @Test\n    fun `Cannot release prisoner if only prisoner is asleep and pet dog is present`() {\n        val knightIsAwake = true\n        val archerIsAwake = true\n        val prisonerIsAwake = false\n        val petDogIsPresent = true\n\n        assertFalse(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n\n    @Test\n    fun `Cannot release prisoner if only prisoner is asleep and pet dog is absent`() {\n        val knightIsAwake = true\n        val archerIsAwake = true\n        val prisonerIsAwake = false\n        val petDogIsPresent = false\n\n        assertFalse(canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent))\n    }\n}\n"
  },
  {
    "path": "exercises/concept/log-levels/.docs/hints.md",
    "content": "# Hints\n\n## General\n\n- Kotlin provides many [functions][ref-strings] for working with Strings. Be sure to check out the `Members & Extensions` tab! \n\n## 1. Get message from a log line\n\n- There is a [function][ref-string-substringAfter] to extract the part of a `String` after a given delimiter.\n- Removing whitespace from a `String` is explored in [Remove All Whitespaces from a String in Kotlin][tutorial-trim-white-space].\n\n## 2. Get log level from a log line\n\n- There is also a [function][ref-string-substringBefore] to extract part of a `String` _before_ a given delimiter.\n- There is a [way][ref-string-lowercase] to change a `String` to lowercase.\n\n## 3. Reformat a log line\n\n- [String templates][docs-string-template] can be done with a [multiline string][docs-string-multiline].\n\n[docs-string-multiline]: https://kotlinlang.org/docs/strings.html#multiline-strings\n[docs-string-template]: https://kotlinlang.org/docs/strings.html#string-templates\n[ref-strings]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/\n[ref-string-indexOf]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/#-537588047%2FFunctions%2F-1430298843\n[ref-string-lowercase]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/#-648004414%2FFunctions%2F-956074838\n[ref-string-substringAfter]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/#1564391517%2FFunctions%2F-1430298843\n[tutorial-search-text-in-string]: https://javarevisited.blogspot.com/2016/10/how-to-check-if-string-contains-another-substring-in-java-indexof-example.html\n[tutorial-trim-white-space]: https://www.baeldung.com/kotlin/string-remove-whitespace\n"
  },
  {
    "path": "exercises/concept/log-levels/.docs/instructions.md",
    "content": "# Instructions\n\nIn this exercise you'll be processing log-liners.\n\nEach log line is a string formatted as follows: \"[<LEVEL>]: <MESSAGE>*\".\n\n## 1. Get the message from a log line\n\nImplement the `LogLevels.message()` function to return the message from a log line, with the leading and trailing whitespaces removed.\n\n## 2. Get the log level from a log line\n\nImplement the `LogLevels.logLevel()` function to return the log level from a log line in lower case.\n\n## 3. Reformat a log line\n\nImplement the `LogLevels.reformat()` method that takes a log line and a location string and reformats into a message containing two lines.\nThe first line is formatted as `<LEVEL>@<LOCATIOON>:`, where:\n\n* `<LEVEL>` is the log level in lower case (as from 2. Get the log level from a log line).\n* `<LOCATION>` is the location given as the second parameter.\n\nThe second line contains exactly two spaces, followed by the log message (as from 1. Get the message from a log line):\n\n```kotlin\nreformat(\"[TRACE]: Start of function\", 2, 8)\n// => \"trace@208:\n  Start of function\"\n```"
  },
  {
    "path": "exercises/concept/log-levels/.docs/introduction.md",
    "content": "# Introduction\n\nA [`string`][ref-string] in Kotlin is an immutable sequence of Unicode characters.\n\n[`Immutable`][wiki-immutable] means that any operation on a string must return a new string: the original string can never change.\n\n[`Unicode`][wiki-unicode] means that most of the world's writing systems can be represented, but (in contrast to older languages such as C) there is no 1:1 mapping between characters and bytes.\n\nA string is usually surrounded by double-quotes `\" \"`.\n\nSome characters need escaping: `\\'`, `\\\\`, plus the usual non-printing characters such as `\\t` (tab) and `\\n` (newline).\n\n```kotlin\nval s = \"Escape apostrophe \\' and backslash \\\\.\"\n// Escape apostrophe ' and backslash \\.\n```\n\nMulti-line strings are surrounded by 3 double-quotes, and can contain arbitrary text (no need for escaping).\n\n```kotlin\nval multi = \"\"\"I'm a\n    multi-line\n    string with special characters \\ \\t \"\"\"\n//I'm a\n//    multi-line\n//    string with special characters  \\ \\t \n```\n\nUse [trimIndent][trimIndent-doc] to remove the common indenting from the lines.\nThis is useful for formatting the string:\n\n```kotlin\nval multi = \"\"\"\n    I'm a\n      multi-line\n    string\"\"\".trimIndent()\n\n//I'm a\n//  multi-line\n//string\n```\n\nAlternatively, [trimMargin][trimMargin-doc] lets you specify a delimiter.\nEach line in the `String` then begins after the delimiter.\nThe delimiter defaults to `|`, but you can specify a different delimiter as a parameter.\nFor example:\n\n```kotlin\nval multi = \"\"\"\n    |I'm a\n    |  multi-line\n    |string\"\"\".trimMargin()\n\n//I'm a\n//  multi-line\n//string\n\nval multi2 = \"\"\"\n    start>I'm a\n    start>  multi-line\n    start>string\"\"\".trimMargin(\"start>\")\n\n//I'm a\n//  multi-line\n//string\n```\n\nStrings can be concatenated with `+`, but this is best limited to short and simple cases.\nThere are other and often better options.\n\n## String templates\n\nThis refers to what some other languages call \"interpolation\".\n\nIf a string contains a dollar sign `$`, followed by an identifier, or contains braces (`{expression}`) surrounding an expression, those are substituted by respectively the value or the result of the expression.\n\n```kotlin\nval x = 42\nval st = \"x is $x, x squared is {x * x}\"\n// x is 42, x squared is 1764\n```\n\nThe braces `{ }` are needed around expressions when parsing would otherwise be ambiguous.\n\nIn general, use of string templates is a more efficient and idiomatic way to combine strings than using `+`.\n\n## String functions\n\nKotlin provides _many_ [`functions`][ref-string-functions] to manipulate strings.\n\nMostly, these are [`extensions functions`][ref-extensions] rather than members of the `String` class, though this has little effect on how we use them.\n\n~~~~exercism/note\nKotlin's rather complex [documentation][ref-string-functions] pages hide extension functions in the default view.\nBe sure to click `Members & Extensions` to expand this section.\n\n[ref-string-functions]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/\n~~~~\n\nThe following examples show just a small selection of what is available:\n\n```kotlin\nval str = \"Hello World!\"\n\nstr.length              // => 12 (a property, not a function)\nstr.elementAt(6)        // => W\nstr.elementAtOrNull(20) // => null (index out of range)\nstr.substring(6, 11)    // => \"World\"\nstr.substringAfter(\" \") // => \"World!\"\n\nstr.lowercase()         // => \"hello world!\"\nstr.uppercase()         // => \"HELLO WORLD!\"\n\nstr.startsWith(\"Hel\")   // => true\nstr.endsWith(\"xyz\")     // => false\nstr.indexOf(\"0\")        // => 4\n\nstr.toCharArray()       // => [H, e, l, l, o,  , W, o, r, l, d, !]\n\"42\".toInt() + 1        // => 43  (parsing; see also toFloat)\n\n\"Howdy!  \".trim()       // => \"Howdy\"\n```\n\n\n[ref-string]: https://kotlinlang.org/docs/strings.html\n[wiki-immutable]: https://en.wikipedia.org/wiki/Immutable_object\n[wiki-unicode]: https://en.wikipedia.org/wiki/Unicode\n[ref-stringbuilder]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-string-builder/\n[ref-extensions]: https://kotlinlang.org/docs/extensions.html#extensions.md\n[ref-string-functions]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/\n[trimIndent-doc]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/trim-indent.html\n[trimMargin-doc]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/trim-margin.html\n"
  },
  {
    "path": "exercises/concept/log-levels/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"kahgoh\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/LogLevels.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/LogLevelsTest.kt\"\n    ],\n    \"exemplar\": [\n      \".meta/src/reference/kotlin/LogLevels.kt\"\n    ]\n  },\n  \"blurb\": \"Learn about strings by processing logs.\"\n}\n"
  },
  {
    "path": "exercises/concept/log-levels/.meta/src/reference/kotlin/LogLevels.kt",
    "content": "fun message(logLine : String) : String {\n    return logLine.substringAfter(\":\").trim()\n}\n\nfun logLevel(logLine : String) : String {\n    return logLine.substringBefore(\":\").removeSurrounding(\"[\", \"]\").lowercase()\n}\n\nfun reformat(logLine : String, location : String) : String {\n    return \"\"\"\n        |${logLevel(logLine)}@$location:\n        |  ${message(logLine)}\n    \"\"\".trimMargin()\n}"
  },
  {
    "path": "exercises/concept/log-levels/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n\n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/concept/log-levels/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/concept/log-levels/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/concept/log-levels/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/concept/log-levels/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/concept/log-levels/src/main/kotlin/LogLevels.kt",
    "content": "fun message(logLine : String) : String {\n    TODO(\"Please implement the message() function\")\n}\n\nfun logLevel(logLine : String) : String {\n    TODO(\"Please implement the logLevel() function\")\n}\n\nfun reformat(logLine : String, location : String) : String {\n    TODO(\"Please implement the reformat() method\")\n}"
  },
  {
    "path": "exercises/concept/log-levels/src/test/kotlin/LogLevelsTest.kt",
    "content": "import kotlin.test.Test\nimport kotlin.test.assertEquals\n\nclass LogLevelsTest {\n    @Test\n    fun `error message`() {\n        assertEquals(\"Stack overflow\", message(\"[ERROR]: Stack overflow\"))\n    }\n\n    @Test\n    fun `warning message`() {\n        assertEquals(\"Disk almost full\", message(\"[WARNING]: Disk almost full\"))\n    }\n\n    @Test\n    fun `info message`() {\n        assertEquals(\"File info\", message(\"[INFO]: File info\"))\n    }\n\n    @Test\n    fun `warning message with leading and trailing whitespace`() {\n        val logLine = \"\"\"[WARNING]:     Timezone not set  \n        \"\"\"\n        assertEquals(\"Timezone not set\", message(logLine))\n    }\n\n    @Test\n    fun `error log level`() {\n        assertEquals(\"error\", logLevel(\"[ERROR]: Stack overflow\"))\n    }\n\n    @Test\n    fun `warning log level`() {\n        assertEquals(\"warning\", logLevel(\"[WARNING]: Disk almost full\"))\n    }\n\n    @Test\n    fun `info log level`() {\n        assertEquals(\"info\", logLevel(\"[INFO]: File info\"))\n    }\n\n    @Test\n    fun `warning log level with leading and trailing whitespace`() {\n        val logLine = \"\"\"[WARNING]:     Timezone not set  \n        \"\"\"\n        assertEquals(\"warning\", logLevel(logLine))\n    }\n\n    @Test\n    fun `reformat error log line`() {\n        val expected = \"\"\"\n           |error@code:\n           |  Segmentation fault\n        \"\"\".trimMargin()\n        assertEquals(expected, reformat(\"[ERROR]: Segmentation fault\", \"code\"))\n    }\n\n    @Test\n    fun `reformat warn log line`() {\n        val expected = \"\"\"\n            |warn@CPU:\n            |  High temperature\n        \"\"\".trimMargin()\n        assertEquals(expected, reformat(\"[WARN]: High temperature\", \"CPU\"))\n    }\n\n    @Test\n    fun `reformat info log line`() {\n        val expected = \"\"\"\n            |info@disk:\n            |  Disk defragmented\n        \"\"\".trimMargin()\n        assertEquals(expected, reformat(\"[INFO]: Disk defragmented\", \"disk\"))\n    }\n\n    @Test\n    fun `reformat a log line with multiple whitespace`() {\n        val expected = \"\"\"\n            |notice@shell:\n            |  Entered bad input too many times! \n            |\n            |  This incident will be reported!\n        \"\"\".trimMargin()\n        val logLine = \"\"\"\n            |[NOTICE]:     Entered bad input too many times! \n            |\n            |  This incident will be reported!               \n                   \n        \"\"\".trimMargin()\n        assertEquals(expected, reformat(logLine, \"shell\"))\n    }\n}"
  },
  {
    "path": "exercises/concept/lucians-luscious-lasagna/.docs/hints.md",
    "content": "# Hints\n\n## General\n\n- An [integer (`Int`) value][numbers] can be defined as one or more consecutive digits.\n- Use variables to give nice and readable names for your values. Remember that code readability is much more important than amount of code lines.\n\n## 1. Calculate remaining baking time in minutes\n\n- You need to define a [function][functions] with a single parameter.\n- You need to assign a [default value][function-defaults] for the parameter.\n- You have to explicitly return an integer value from a method.\n- The method's parameter is an [integer][numbers].\n- You need to use the mathematical operator for subtraction (`-`) to subtract values.\n\n## 2. Calculate the preparation time in minutes\n\n- You need to define a [function][functions] with a single parameter.\n- You have to explicitly return an integer value from a method.\n- The method's parameter is an [integer][numbers].\n- You need to use the mathematical operator for addition (`+`) to add values.\n\n## 3. Calculate the elapsed time in minutes\n\n- You need to define a [function][functions] with a two parameters.\n- You need to assign a [default value][function-defaults] for the second parameter.\n- You have to explicitly return an integer value from a method.\n- The method's parameter is an [integer][numbers].\n- You need to use the mathematical operator for addition (`+`) to add values.\n- You need to call already implemented functions.\n\n[numbers]: https://kotlinlang.org/docs/reference/basic-types.html#numbers\n[functions]: https://kotlinlang.org/docs/reference/functions.html#function-declarations\n[function-defaults]: https://kotlinlang.org/docs/reference/functions.html#default-arguments\n"
  },
  {
    "path": "exercises/concept/lucians-luscious-lasagna/.docs/instructions.md",
    "content": "# Instructions\n\nThe owner of your local pizza place has asked you to help her to calculate cooking times for different pizzas. In this exercise you're going to write few functions to calculate that.\n\nYou have three tasks.\n\n## 1. Calculate remaining baking time in minutes\n\nDefine and implement the `remainingMinutesInOven()` function that will count how many more minutes you need to keep the pizza in the oven.\n\nThe function should accept one **optional** parameter (with default value) for the amount of minutes that passed since you've started baking pizza. If the parameter is missing - assume that you've just put pizza into the oven and **0 (zero)** minutes passed already.\n\nFor simplicity - let's assume that all types of pizzas require exactly 40 minutes in the oven to be ready.\n\n```kotlin\nremainingMinutesInOven()   // => 40\n\nremainingMinutesInOven(10)   // => 30\n```\n\n## 2. Calculate the preparation time in minutes\n\nBefore baking the pizza, you need to prepare the dough, roll it out and put toppings onto it.\n\nDefine and implement the `preparationTimeInMinutes()` function that will count how many minutes it will take to prepare pizza before putting it into the oven.\n\nThe function should accept one **required** parameter (`numberOfIngredientTypes`) for the number of topping ingredient types that will be used.\n\nAssume that you need 5 minutes to make and roll out dough and 2 minutes for using **each** kind of topping.\n\n```kotlin\npreparationTimeInMinutes(0) // => 5\n\npreparationTimeInMinutes(1) // => 7\n```\n\n## 3. Calculate the elapsed time in minutes\n\nDefine and implement the `elapsedCookingTimeInMinutes()` function that will count how many minutes it will take to prepare, bake and serve the pizza. Use the functions from the previous steps while making the calculations.\n\nThe function should accept two parameters. The first one is **required** and is the number of topping ingredient types. The second one is **optional** and is the serving time in minutes (assume that is 0 if not provided).\n\n```kotlin\nelapsedCookingTimeInMinutes(1)  // => 47\n\nelapsedCookingTimeInMinutes(2, 3)  // => 52\n```\n"
  },
  {
    "path": "exercises/concept/lucians-luscious-lasagna/.docs/introduction.md",
    "content": "# Introduction\n\nKotlin is a **statically typed** programming language developed by JetBrains. This means that the type of variables is defined at compile-time.\n\n## Variables\n\nSimilarly to other statically-typed programming languages, the type of each variable should be defined at compile time. You can avoid explicit type declarations where they can be inferred by the compiler from their context.\n\nKotlin has immutable (`val`) and mutable (`var`) variables. The value of an immutable variable can't be changed after it's initial value is assigned. Most of the time you will use this type of variable.\n\n```kotlin\nval robotName = \"HAL-9000\"\nuserId = \"T-1000\"  // This will not compile\n```\n\nA mutable variable's value can be changed one or more times:\n\n```kotlin\nvar index = 12\nprint(index)  // 12\n\nindex = 100\nprint(index)  // 100\n```\n\nSemicolons in Kotlin are optional, except for a few special cases that will be covered later.\n\n## Functions\n\nFunctions in Kotlin are defined with the `fun` keyword and are _first-class citizens_ (not related to OOP). It means that you can declare (so-called `top-level functions`) them right in files (e.g. in Java you can define methods only in classes, not in files):\n\n```kotlin\n// This is content of the Hello.kt file\n\nfun hello() {}\n```\n\nFunctions can receive arguments. Each argument has a name and a type. Unlike variables, the type of arguments can't be inferred. Functions can have zero or more arguments:\n\n```kotlin\nfun hello() {}\n\nfun hello(name: String) {}\n\nfun hello(name: String, age: Int) {}\n```\n\nKotlin functions might or might not return a value:\n\n```kotlin\nfun min(a: Int, b: Int): Int\n\nfun countBonuses(user: User): Bonuses\n\nfun run() {}\n```\n\nTo return a value from a function, the `return` keyword is used:\n\n```kotlin\nfun getName(): String {\n    return \"Alice\"\n}\n```\n\nFunctions can have parameters with default values. These values will be used if they are omitted where function is invoked:\n\n```kotlin\nfun ping(host: String = \"localhost\") {\n    println(\"PING --> $host\")\n}\n\nping(\"exercism.io\")  // PING --> exercism.io\nping()               // PING --> localhost\n```\n\n## Comments\n\nUse `//` to define single-line comment:\n\n```kotlin\nfoo() // Everything after `//` will be ignored by compiler\n\n// I will be ignored too\n```\n\nor `/*` and `*/` to define multi-line comments:\n\n```kotlin\n/*\n   This this an example\n   for a multiline comment\n*/\n```\n"
  },
  {
    "path": "exercises/concept/lucians-luscious-lasagna/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"dector\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/LuciansLusciousLasagna.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/LuciansLusciousLasagnaTests.kt\"\n    ],\n    \"exemplar\": [\n      \".meta/src/reference/kotlin/LuciansLusciousLasagna.kt\"\n    ]\n  },\n  \"forked_from\": [\n    \"fsharp/lucians-luscious-lasagna\"\n  ],\n  \"blurb\": \"Learn about the basics of Kotlin by following a lasagna recipe.\"\n}\n"
  },
  {
    "path": "exercises/concept/lucians-luscious-lasagna/.meta/design.md",
    "content": "# Design\n\n## Goal\n\nThis exercise should teach bare minimum to help students understand Kotlin programs.\n\n## Learning objectives\n\n- Know what a variable is.\n- Know how to define a variable.\n- Know the difference between immutable and mutable variable.\n- Know how to update a variable.\n- Know how to define a method.\n- Know how to return a value from a method.\n- Know how to call a method.\n- Know about basic types: Int, Unit.\n- Know how to define single and multiline comments.\n\n## Out of scope\n\n- More advanced data types: String, Float/Double/Number, Nothing etc.\n- Calling function with named parameters.\n- Inline functions.\n- Classes/Objects.\n- Packages\n\n## Concepts\n\nThe Concepts this exercise unlocks are:\n\n- `basics`: know what a variable is; know how to define a variable; know the difference between immutable and mutable variable; know how to update a variable; know how to define a method; know how to return a value from a method; know how to call a method; know that methods must be defined in classes; know about basic types: Int, Unit; know how to define single and multiline comments.\n\n## Prerequisites\n\n_none_\n\n## Resources to refer to\n\n[Kotlin docs](https://kotlinlang.org/docs/reference/basic-syntax.html)\n\n## Representer\n\n## Analyzer\n"
  },
  {
    "path": "exercises/concept/lucians-luscious-lasagna/.meta/src/reference/kotlin/LuciansLusciousLasagna.kt",
    "content": "fun remainingMinutesInOven(actualMinutesInOven: Int = 0): Int {\n    val cookingTime = 40\n\n    return cookingTime - actualMinutesInOven\n}\n\nfun preparationTimeInMinutes(numberOfIngredientTypes: Int): Int {\n    return 5 + numberOfIngredientTypes * 2\n}\n\nfun elapsedCookingTimeInMinutes(numberOfIngredientTypes: Int, servingTimeInMinutes: Int = 0): Int {\n    val preparationTime = preparationTimeInMinutes(numberOfIngredientTypes)\n    val backingTime = remainingMinutesInOven()\n\n    return preparationTime + backingTime + servingTimeInMinutes\n}\n"
  },
  {
    "path": "exercises/concept/lucians-luscious-lasagna/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n\n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/concept/lucians-luscious-lasagna/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/concept/lucians-luscious-lasagna/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/concept/lucians-luscious-lasagna/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/concept/lucians-luscious-lasagna/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/concept/lucians-luscious-lasagna/src/main/kotlin/LuciansLusciousLasagna.kt",
    "content": "// TODO: define `remainingMinutesInOven()`. Use named variable to store expected time in oven.\n\n// TODO: define `preparationTimeInMinutes()`.\n\n// TODO: define `elapsedCookingTimeInMinutes()`.\n"
  },
  {
    "path": "exercises/concept/lucians-luscious-lasagna/src/test/kotlin/LuciansLusciousLasagnaTests.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertFalse\nimport kotlin.test.assertTrue\n\nclass LuciansLusciousLasagnaTests {\n    @Test\n    fun `test`()\n    {\n\n    }\n}\n"
  },
  {
    "path": "exercises/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/gradle.properties",
    "content": "kotlin.incremental=false\norg.gradle.parallel=true\n"
  },
  {
    "path": "exercises/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/gradlew.bat",
    "content": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\r\n@rem you may not use this file except in compliance with the License.\r\n@rem You may obtain a copy of the License at\r\n@rem\r\n@rem      https://www.apache.org/licenses/LICENSE-2.0\r\n@rem\r\n@rem Unless required by applicable law or agreed to in writing, software\r\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\r\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n@rem See the License for the specific language governing permissions and\r\n@rem limitations under the License.\r\n@rem\r\n\r\n@if \"%DEBUG%\"==\"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\r\n@rem This is normally unused\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\r\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif %ERRORLEVEL% equ 0 goto execute\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto execute\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif %ERRORLEVEL% equ 0 goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nset EXIT_CODE=%ERRORLEVEL%\r\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\r\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\r\nexit /b %EXIT_CODE%\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "exercises/practice/accumulate/.docs/instructions.md",
    "content": "# Instructions\n\nImplement the `accumulate` operation, which, given a collection and an\noperation to perform on each element of the collection, returns a new\ncollection containing the result of applying that operation to each element of\nthe input collection.\n\nGiven the collection of numbers:\n\n- 1, 2, 3, 4, 5\n\nAnd the operation:\n\n- square a number (`x => x * x`)\n\nYour code should be able to produce the collection of squares:\n\n- 1, 4, 9, 16, 25\n\nCheck out the test suite to see the expected function signature.\n\n## Restrictions\n\nKeep your hands off that collect/map/fmap/whatchamacallit functionality\nprovided by your standard library!\nSolve this one yourself using other basic tools instead.\n"
  },
  {
    "path": "exercises/practice/accumulate/.meta/config.json",
    "content": "{\n  \"blurb\": \"Implement the `accumulate` operation, which, given a collection and an operation to perform on each element of the collection, returns a new collection containing the result of applying that operation to each element of the input collection.\",\n  \"authors\": [\"sdavids13\"],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"kytrinyx\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\"src/main/kotlin/Accumulate.kt\"],\n    \"test\": [\"src/test/kotlin/AccumulateTest.kt\"],\n    \"example\": [\".meta/src/reference/kotlin/Accumulate.kt\"]\n  },\n  \"source\": \"Conversation with James Edward Gray II\",\n  \"source_url\": \"https://twitter.com/jeg2\"\n}\n"
  },
  {
    "path": "exercises/practice/accumulate/.meta/src/reference/kotlin/Accumulate.kt",
    "content": "object Accumulate {\n    fun <T, R> accumulate(collection: List<T>, function: (T) -> R): List<R> {\n        val retVal = mutableListOf<R>()\n        for(item in collection) {\n            retVal.add(function.invoke(item))\n        }\n        return retVal\n    }\n}\n"
  },
  {
    "path": "exercises/practice/accumulate/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/accumulate/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/accumulate/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/accumulate/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/accumulate/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/accumulate/src/main/kotlin/Accumulate.kt",
    "content": "object Accumulate {\n    fun accumulate(collection: List<Any>, converter: (Any) -> Any): List<Any> {\n        TODO(\"Change the function signature and implement it to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/accumulate/src/test/kotlin/AccumulateTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass AccumulateTest {\n\n\n    @Test\n    fun emptyAccumulateProducesEmptyAccumulation() {\n        val input = listOf<Int>()\n        val expectedOutput = listOf<Int>()\n        assertEquals(expectedOutput, Accumulate.accumulate(input, { x -> x * x }))\n    }\n\n    @Ignore\n    @Test\n    fun accumulateSquares() {\n        val input = listOf(1, 2, 3)\n        val expectedOutput = listOf(1, 4, 9)\n        assertEquals(expectedOutput, Accumulate.accumulate(input, { x -> x * x }))\n    }\n\n    @Ignore\n    @Test\n    fun accumulateUpperCases() {\n        val input = listOf(\"hello\", \"world\")\n        val expectedOutput = listOf(\"HELLO\", \"WORLD\")\n        assertEquals(expectedOutput, Accumulate.accumulate(input, { it.toUpperCase() }))\n    }\n\n    @Ignore\n    @Test\n    fun accumulateReversedStrings() {\n        val input = \"the quick brown fox etc\".split(\" \")\n        val expectedOutput = \"eht kciuq nworb xof cte\".split(\" \")\n        assertEquals(expectedOutput, Accumulate.accumulate(input, { it.reversed() }))\n    }\n\n    @Ignore\n    @Test\n    fun accumulateWithinAccumulate() {\n        val input1 = listOf(\"a\", \"b\", \"c\")\n        val input2 = listOf(\"1\", \"2\", \"3\")\n        val expectedOutput = listOf(\"a1 a2 a3\", \"b1 b2 b3\", \"c1 c2 c3\")\n        assertEquals(expectedOutput, Accumulate.accumulate(input1,\n                { c -> Accumulate.accumulate(input2, { d -> c + d }).joinToString(\" \") }\n        ))\n    }\n\n    @Ignore\n    @Test\n    fun accumulateToDifferentType() {\n        val input = listOf(1, 2, 3)\n        val expectedOutput = listOf(\"1\", \"2\", \"3\")\n        assertEquals(expectedOutput, Accumulate.accumulate(input, { it.toString() }))\n    }\n}\n"
  },
  {
    "path": "exercises/practice/acronym/.docs/instructions.md",
    "content": "# Instructions\n\nConvert a phrase to its acronym.\n\nTechies love their TLA (Three Letter Acronyms)!\n\nHelp generate some jargon by writing a program that converts a long name like Portable Network Graphics to its acronym (PNG).\n\nPunctuation is handled as follows: hyphens are word separators (like whitespace); all other punctuation can be removed from the input.\n\nFor example:\n\n| Input                     | Output |\n| ------------------------- | ------ |\n| As Soon As Possible       | ASAP   |\n| Liquid-crystal display    | LCD    |\n| Thank George It's Friday! | TGIF   |\n"
  },
  {
    "path": "exercises/practice/acronym/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"beatbrot\",\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"kytrinyx\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Acronym.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/AcronymTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Acronym.kt\"\n    ]\n  },\n  \"blurb\": \"Convert a long phrase to its acronym.\",\n  \"source\": \"Julien Vanier\",\n  \"source_url\": \"https://github.com/monkbroc\"\n}\n"
  },
  {
    "path": "exercises/practice/acronym/.meta/src/reference/kotlin/Acronym.kt",
    "content": "object Acronym {\n    fun generate(phrase: String) = Regex(\"[A-Z]+[a-z]*|[a-z]+\")\n            .findAll(phrase.replace(\"'\", \"\"))\n            .map { it.value.first().uppercaseChar() }\n            .joinToString(\"\")\n}\n"
  },
  {
    "path": "exercises/practice/acronym/.meta/tests.toml",
    "content": "# This is an auto-generated file.\n#\n# Regenerating this file via `configlet sync` will:\n# - Recreate every `description` key/value pair\n# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications\n# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)\n# - Preserve any other key/value pair\n#\n# As user-added comments (using the # character) will be removed when this file\n# is regenerated, comments can be added via a `comment` key.\n\n[1e22cceb-c5e4-4562-9afe-aef07ad1eaf4]\ndescription = \"basic\"\n\n[79ae3889-a5c0-4b01-baf0-232d31180c08]\ndescription = \"lowercase words\"\n\n[ec7000a7-3931-4a17-890e-33ca2073a548]\ndescription = \"punctuation\"\n\n[32dd261c-0c92-469a-9c5c-b192e94a63b0]\ndescription = \"all caps word\"\n\n[ae2ac9fa-a606-4d05-8244-3bcc4659c1d4]\ndescription = \"punctuation without whitespace\"\n\n[0e4b1e7c-1a6d-48fb-81a7-bf65eb9e69f9]\ndescription = \"very long abbreviation\"\n\n[6a078f49-c68d-4b7b-89af-33a1a98c28cc]\ndescription = \"consecutive delimiters\"\n\n[5118b4b1-4572-434c-8d57-5b762e57973e]\ndescription = \"apostrophes\"\n\n[adc12eab-ec2d-414f-b48c-66a4fc06cdef]\ndescription = \"underscore emphasis\"\n"
  },
  {
    "path": "exercises/practice/acronym/.meta/version",
    "content": "1.7.0\n"
  },
  {
    "path": "exercises/practice/acronym/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/acronym/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/acronym/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/acronym/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/acronym/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/acronym/src/main/kotlin/Acronym.kt",
    "content": "object Acronym {\n    fun generate(phrase: String) : String {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/acronym/src/test/kotlin/AcronymTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass AcronymTest {\n    @Test\n    fun `capitalized words`() = assertAcronymEquals(\n            \"Portable Network Graphics\",\n            \"PNG\")\n\n    @Ignore\n    @Test\n    fun `lowercase word in the middle`() = assertAcronymEquals(\n            \"Ruby on Rails\",\n            \"ROR\")\n\n    @Ignore\n    @Test\n    fun `punctuation is ignored`() = assertAcronymEquals(\n            \"First In, First Out\",\n            \"FIFO\")\n\n    @Ignore\n    @Test\n    fun `uppercased word at the start`() = assertAcronymEquals(\n            \"GNU Image Manipulation Program\",\n            \"GIMP\")\n\n    @Ignore\n    @Test\n    fun `hyphen is ignored`() = assertAcronymEquals(\n            \"Complementary metal-oxide semiconductor\",\n            \"CMOS\")\n\n    @Ignore\n    @Test\n    fun `lots of words`() = assertAcronymEquals(\n            \"Rolling On The Floor Laughing So Hard That My Dogs Came Over And Licked Me\",\n            \"ROTFLSHTMDCOALM\")\n\n    @Ignore\n    @Test\n    fun `consecutive delimiters`() = assertAcronymEquals(\n            \"Something - I made up from thin air\",\n            \"SIMUFTA\")\n\n    @Ignore\n    @Test\n    fun `apostrophe is ignored`() = assertAcronymEquals(\n            \"Halley's Comet\",\n            \"HC\")\n\n    @Ignore\n    @Test\n    fun `underscore emphasis is ignored`() = assertAcronymEquals(\n            \"The Road _Not_ Taken\",\n            \"TRNT\")\n}\n\nprivate fun assertAcronymEquals(origin: String, acronym: String) = assertEquals(acronym, Acronym.generate(origin))\n"
  },
  {
    "path": "exercises/practice/affine-cipher/.docs/instructions.md",
    "content": "# Instructions\n\nCreate an implementation of the affine cipher, an ancient encryption system created in the Middle East.\n\nThe affine cipher is a type of monoalphabetic substitution cipher.\nEach character is mapped to its numeric equivalent, encrypted with a mathematical function and then converted to the letter relating to its new numeric value.\nAlthough all monoalphabetic ciphers are weak, the affine cipher is much stronger than the Atbash cipher, because it has many more keys.\n\n[//]: # \" monoalphabetic as spelled by Merriam-Webster, compare to polyalphabetic \"\n\n## Encryption\n\nThe encryption function is:\n\n```text\nE(x) = (ai + b) mod m\n```\n\nWhere:\n\n- `i` is the letter's index from `0` to the length of the alphabet - 1.\n- `m` is the length of the alphabet.\n  For the Latin alphabet `m` is `26`.\n- `a` and `b` are integers which make up the encryption key.\n\nValues `a` and `m` must be _coprime_ (or, _relatively prime_) for automatic decryption to succeed, i.e., they have number `1` as their only common factor (more information can be found in the [Wikipedia article about coprime integers][coprime-integers]).\nIn case `a` is not coprime to `m`, your program should indicate that this is an error.\nOtherwise it should encrypt or decrypt with the provided key.\n\nFor the purpose of this exercise, digits are valid input but they are not encrypted.\nSpaces and punctuation characters are excluded.\nCiphertext is written out in groups of fixed length separated by space, the traditional group size being `5` letters.\nThis is to make it harder to guess encrypted text based on word boundaries.\n\n## Decryption\n\nThe decryption function is:\n\n```text\nD(y) = (a^-1)(y - b) mod m\n```\n\nWhere:\n\n- `y` is the numeric value of an encrypted letter, i.e., `y = E(x)`\n- it is important to note that `a^-1` is the modular multiplicative inverse (MMI) of `a mod m`\n- the modular multiplicative inverse only exists if `a` and `m` are coprime.\n\nThe MMI of `a` is `x` such that the remainder after dividing `ax` by `m` is `1`:\n\n```text\nax mod m = 1\n```\n\nMore information regarding how to find a Modular Multiplicative Inverse and what it means can be found in the [related Wikipedia article][mmi].\n\n## General Examples\n\n- Encrypting `\"test\"` gives `\"ybty\"` with the key `a = 5`, `b = 7`\n- Decrypting `\"ybty\"` gives `\"test\"` with the key `a = 5`, `b = 7`\n- Decrypting `\"ybty\"` gives `\"lqul\"` with the wrong key `a = 11`, `b = 7`\n- Decrypting `\"kqlfd jzvgy tpaet icdhm rtwly kqlon ubstx\"` gives `\"thequickbrownfoxjumpsoverthelazydog\"` with the key `a = 19`, `b = 13`\n- Encrypting `\"test\"` with the key `a = 18`, `b = 13` is an error because `18` and `26` are not coprime\n\n## Example of finding a Modular Multiplicative Inverse (MMI)\n\nFinding MMI for `a = 15`:\n\n- `(15 * x) mod 26 = 1`\n- `(15 * 7) mod 26 = 1`, ie. `105 mod 26 = 1`\n- `7` is the MMI of `15 mod 26`\n\n[mmi]: https://en.wikipedia.org/wiki/Modular_multiplicative_inverse\n[coprime-integers]: https://en.wikipedia.org/wiki/Coprime_integers\n"
  },
  {
    "path": "exercises/practice/affine-cipher/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/AffineCipher.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/AffineCipherTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/AffineCipher.kt\"\n    ]\n  },\n  \"blurb\": \"Create an implementation of the Affine cipher, an ancient encryption algorithm from the Middle East.\",\n  \"source\": \"Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Affine_cipher\"\n}\n"
  },
  {
    "path": "exercises/practice/affine-cipher/.meta/src/reference/kotlin/AffineCipher.kt",
    "content": "object AffineCipher {\n\n    /** Number of characters in the alphabet (a-z). */\n    private const val ALPHABET_SIZE = 26\n\n    /** Number of space separated groups in the encoded text. */\n    private const val GROUP_SIZE = 5\n\n    fun encode(cipheredMessage: String, a: Int, b: Int): String {\n        return translate(cipheredMessage, a, b, encode = true)\n                .windowed(GROUP_SIZE, GROUP_SIZE, true)\n                .joinToString(\" \")\n    }\n\n    fun decode(cipheredMessage: String, a: Int, b: Int): String {\n        return translate(cipheredMessage, a, b, encode = false)\n    }\n\n    private fun modularMultiplicativeInverse(a: Int): Int =\n            (1..ALPHABET_SIZE)\n                    .firstOrNull { ((a * it) % ALPHABET_SIZE) == 1 }\n                    ?: 1\n\n    private fun translate(text: String, a: Int, b: Int, encode: Boolean): String {\n        val inv = modularMultiplicativeInverse(a)\n        require(inv != 1) { \"Key A and alphabet size must be coprime!\" }\n\n        return text\n            .lowercase()\n                .mapNotNull { c ->\n                    when {\n                        c.isDigit() -> c\n                        c.isLetter() ->\n                            (c - 'a') // the characters alphabetical position, not its ASCII value\n                                .let { if (encode) (a * it + b) else (inv * (it - b)) } // the main algorithm\n                                .let { 'a' + (it % ALPHABET_SIZE) } // map number to character\n                                .let { if (it < 'a') (it + ALPHABET_SIZE) else it } // adjust for negative values\n                        else -> null // spaces and the like are ignored\n                    }\n                }\n                .joinToString(\"\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/affine-cipher/.meta/tests.toml",
    "content": "# This is an auto-generated file.\n#\n# Regenerating this file via `configlet sync` will:\n# - Recreate every `description` key/value pair\n# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications\n# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)\n# - Preserve any other key/value pair\n#\n# As user-added comments (using the # character) will be removed when this file\n# is regenerated, comments can be added via a `comment` key.\n\n[2ee1d9af-1c43-416c-b41b-cefd7d4d2b2a]\ndescription = \"encode -> encode yes\"\n\n[785bade9-e98b-4d4f-a5b0-087ba3d7de4b]\ndescription = \"encode -> encode no\"\n\n[2854851c-48fb-40d8-9bf6-8f192ed25054]\ndescription = \"encode -> encode OMG\"\n\n[bc0c1244-b544-49dd-9777-13a770be1bad]\ndescription = \"encode -> encode O M G\"\n\n[381a1a20-b74a-46ce-9277-3778625c9e27]\ndescription = \"encode -> encode mindblowingly\"\n\n[6686f4e2-753b-47d4-9715-876fdc59029d]\ndescription = \"encode -> encode numbers\"\n\n[ae23d5bd-30a8-44b6-afbe-23c8c0c7faa3]\ndescription = \"encode -> encode deep thought\"\n\n[c93a8a4d-426c-42ef-9610-76ded6f7ef57]\ndescription = \"encode -> encode all the letters\"\n\n[0673638a-4375-40bd-871c-fb6a2c28effb]\ndescription = \"encode -> encode with a not coprime to m\"\n\n[3f0ac7e2-ec0e-4a79-949e-95e414953438]\ndescription = \"decode -> decode exercism\"\n\n[241ee64d-5a47-4092-a5d7-7939d259e077]\ndescription = \"decode -> decode a sentence\"\n\n[33fb16a1-765a-496f-907f-12e644837f5e]\ndescription = \"decode -> decode numbers\"\n\n[20bc9dce-c5ec-4db6-a3f1-845c776bcbf7]\ndescription = \"decode -> decode all the letters\"\n\n[623e78c0-922d-49c5-8702-227a3e8eaf81]\ndescription = \"decode -> decode with no spaces in input\"\n\n[58fd5c2a-1fd9-4563-a80a-71cff200f26f]\ndescription = \"decode -> decode with too many spaces\"\n\n[b004626f-c186-4af9-a3f4-58f74cdb86d5]\ndescription = \"decode -> decode with a not coprime to m\"\n"
  },
  {
    "path": "exercises/practice/affine-cipher/.meta/version",
    "content": "2.0.0\n"
  },
  {
    "path": "exercises/practice/affine-cipher/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/affine-cipher/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/affine-cipher/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/affine-cipher/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/affine-cipher/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/affine-cipher/src/main/kotlin/AffineCipher.kt",
    "content": "object AffineCipher {\n\n    fun encode(input: String, a: Int, b: Int) {\n        TODO(\"Implement the function to complete the task\")\n    }\n\n    fun decode(input: String, a: Int, b: Int) {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/affine-cipher/src/test/kotlin/AffineCipherTest.kt",
    "content": "import kotlin.test.Ignore\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\nimport kotlin.test.assertFailsWith\n\nclass AffineCipherTest {\n\n    @Test\n    fun `encode yes`() = assertEquals(\"xbt\", AffineCipher.encode(\"yes\", 5, 7))\n\n    @Ignore\n    @Test\n    fun `encode no`() = assertEquals(\"fu\", AffineCipher.encode(\"no\", 15, 18))\n\n    @Ignore\n    @Test\n    fun `encode OMG`() = assertEquals(\"lvz\", AffineCipher.encode(\"OMG\", 21, 3))\n\n    @Ignore\n    @Test\n    fun `encode O M G`() = assertEquals(\"hjp\", AffineCipher.encode(\"O M G\", 25, 47))\n\n    @Ignore\n    @Test\n    fun `encode mindblowingly`() = assertEquals(\"rzcwa gnxzc dgt\", AffineCipher.encode(\"mindblowingly\", 11, 15))\n\n    @Ignore\n    @Test\n    fun `encode numbers`() = assertEquals(\"jqgjc rw123 jqgjc rw\", AffineCipher.encode(\"Testing,1 2 3, testing.\", 3, 4))\n\n    @Ignore\n    @Test\n    fun `encode deep thought`() = assertEquals(\"iynia fdqfb ifje\", AffineCipher.encode(\"Truth is fiction.\", 5, 17))\n\n    @Ignore\n    @Test\n    fun `encode all letters`() = assertEquals(\"swxtj npvyk lruol iejdc blaxk swxmh qzglf\", AffineCipher.encode(\"The quick brown fox jumps over the lazy dog.\", 17, 33))\n\n    @Ignore\n    @Test\n    fun `encode with a not coprime to m`() {\n        assertFailsWith<IllegalArgumentException>(\"a and m must be coprime.\") {\n            AffineCipher.encode(\"This is a test.\", 6, 17)\n        }\n    }\n\n    @Ignore\n    @Test\n    fun `decode exercism`() = assertEquals(\"exercism\", AffineCipher.decode(\"tytgn fjr\", 3, 7))\n\n    @Ignore\n    @Test\n    fun `decode a sentence`() = assertEquals(\"anobstacleisoftenasteppingstone\", AffineCipher.decode(\"qdwju nqcro muwhn odqun oppmd aunwd o\", 19, 16))\n\n    @Ignore\n    @Test\n    fun `decode numbers`() = assertEquals(\"testing123testing\", AffineCipher.decode(\"odpoz ub123 odpoz ub\", 25, 7))\n\n    @Ignore\n    @Test\n    fun `decode all the letters`() = assertEquals(\"thequickbrownfoxjumpsoverthelazydog\", AffineCipher.decode(\"swxtj npvyk lruol iejdc blaxk swxmh qzglf\", 17, 33))\n\n    @Ignore\n    @Test\n    fun `decode with no spaces in input`() = assertEquals(\"thequickbrownfoxjumpsoverthelazydog\", AffineCipher.decode(\"swxtjnpvyklruoliejdcblaxkswxmhqzglf\", 17, 33))\n\n    @Ignore\n    @Test\n    fun `decode with too many spaces`() = assertEquals(\"jollygreengiant\", AffineCipher.decode(\"vszzm    cly   yd cg    qdp\", 15, 16))\n\n    @Ignore\n    @Test\n    fun `decode with a not coprime to m`() {\n        assertFailsWith<IllegalArgumentException>(\"a and m must be coprime.\") {\n            AffineCipher.decode(\"Test\", 13, 5)\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/all-your-base/.docs/instructions.md",
    "content": "# Instructions\n\nConvert a sequence of digits in one base, representing a number, into a sequence of digits in another base, representing the same number.\n\n~~~~exercism/note\nTry to implement the conversion yourself.\nDo not use something else to perform the conversion for you.\n~~~~\n\n## About [Positional Notation][positional-notation]\n\nIn positional notation, a number in base **b** can be understood as a linear combination of powers of **b**.\n\nThe number 42, _in base 10_, means:\n\n`(4 × 10¹) + (2 × 10⁰)`\n\nThe number 101010, _in base 2_, means:\n\n`(1 × 2⁵) + (0 × 2⁴) + (1 × 2³) + (0 × 2²) + (1 × 2¹) + (0 × 2⁰)`\n\nThe number 1120, _in base 3_, means:\n\n`(1 × 3³) + (1 × 3²) + (2 × 3¹) + (0 × 3⁰)`\n\n_Yes. Those three numbers above are exactly the same. Congratulations!_\n\n[positional-notation]: https://en.wikipedia.org/wiki/Positional_notation\n"
  },
  {
    "path": "exercises/practice/all-your-base/.docs/introduction.md",
    "content": "# Introduction\n\nYou've just been hired as professor of mathematics.\nYour first week went well, but something is off in your second week.\nThe problem is that every answer given by your students is wrong!\nLuckily, your math skills have allowed you to identify the problem: the student answers _are_ correct, but they're all in base 2 (binary)!\nAmazingly, it turns out that each week, the students use a different base.\nTo help you quickly verify the student answers, you'll be building a tool to translate between bases.\n"
  },
  {
    "path": "exercises/practice/all-your-base/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"sophiekoonin\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/BaseConverter.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/BaseConverterTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/BaseConverter.kt\"\n    ]\n  },\n  \"blurb\": \"Convert a number, represented as a sequence of digits in one base, to any other base.\"\n}\n"
  },
  {
    "path": "exercises/practice/all-your-base/.meta/src/reference/kotlin/BaseConverter.kt",
    "content": "import kotlin.math.floor\nimport kotlin.math.pow\n\nclass BaseConverter(originalBase: Int, originalDigits: IntArray) {\n\n    companion object {\n        private const val MINIMUM_VALID_BASE = 2\n        private const val INVALID_BASE_ERROR_MESSAGE = \"Bases must be at least 2.\"\n    }\n\n    private val numeral: Int\n\n    init {\n        require(originalBase >= MINIMUM_VALID_BASE) { INVALID_BASE_ERROR_MESSAGE }\n        require(originalDigits.isNotEmpty()) { \"You must supply at least one digit.\" }\n        require(originalDigits.size == 1 || originalDigits[0] != 0) { \"Digits may not contain leading zeros.\" }\n        require(originalDigits.minOrNull()!! >= 0) { \"Digits may not be negative.\" }\n        require(originalDigits.maxOrNull()!! < originalBase) { \"All digits must be strictly less than the base.\" }\n\n        this.numeral = computeNumeral(originalBase, originalDigits)\n    }\n\n    fun convertToBase(newBase: Int): IntArray {\n        require(newBase >= MINIMUM_VALID_BASE) { INVALID_BASE_ERROR_MESSAGE }\n\n        val largestExponent = computeLargestExponentForBase(newBase)\n        val result = IntArray(largestExponent + 1)\n        var remainder = numeral\n\n        for (currentExponent in largestExponent downTo 0) {\n            val coefficient = floor(remainder / newBase.toDouble().pow(currentExponent.toDouble())).toInt()\n\n            result[largestExponent - currentExponent] = coefficient\n\n            remainder -= (coefficient * newBase.toDouble().pow(currentExponent.toDouble())).toInt()\n        }\n\n        return result\n    }\n\n    private fun computeNumeral(originalBase: Int, originalDigits: IntArray): Int {\n        val largestExponent = originalDigits.size - 1\n\n        val result = (largestExponent downTo 0).sumOf { exponent ->\n            (originalDigits[largestExponent - exponent]\n                    * originalBase.toDouble().pow(exponent.toDouble())).toInt()\n        }\n\n        return result\n    }\n\n    private fun computeLargestExponentForBase(newBase: Int): Int {\n        var result = 0\n\n        while (newBase.toDouble().pow((result + 1).toDouble()) < numeral) {\n            result += 1\n        }\n\n        return result\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/all-your-base/.meta/tests.toml",
    "content": "# This is an auto-generated file.\n#\n# Regenerating this file via `configlet sync` will:\n# - Recreate every `description` key/value pair\n# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications\n# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)\n# - Preserve any other key/value pair\n#\n# As user-added comments (using the # character) will be removed when this file\n# is regenerated, comments can be added via a `comment` key.\n\n[5ce422f9-7a4b-4f44-ad29-49c67cb32d2c]\ndescription = \"single bit one to decimal\"\n\n[0cc3fea8-bb79-46ac-a2ab-5a2c93051033]\ndescription = \"binary to single decimal\"\n\n[f12db0f9-0d3d-42c2-b3ba-e38cb375a2b8]\ndescription = \"single decimal to binary\"\n\n[2c45cf54-6da3-4748-9733-5a3c765d925b]\ndescription = \"binary to multiple decimal\"\n\n[65ddb8b4-8899-4fcc-8618-181b2cf0002d]\ndescription = \"decimal to binary\"\n\n[8d418419-02a7-4824-8b7a-352d33c6987e]\ndescription = \"trinary to hexadecimal\"\n\n[d3901c80-8190-41b9-bd86-38d988efa956]\ndescription = \"hexadecimal to trinary\"\n\n[5d42f85e-21ad-41bd-b9be-a3e8e4258bbf]\ndescription = \"15-bit integer\"\n\n[d68788f7-66dd-43f8-a543-f15b6d233f83]\ndescription = \"empty list\"\n\n[5e27e8da-5862-4c5f-b2a9-26c0382b6be7]\ndescription = \"single zero\"\n\n[2e1c2573-77e4-4b9c-8517-6c56c5bcfdf2]\ndescription = \"multiple zeros\"\n\n[3530cd9f-8d6d-43f5-bc6e-b30b1db9629b]\ndescription = \"leading zeros\"\n\n[a6b476a1-1901-4f2a-92c4-4d91917ae023]\ndescription = \"input base is one\"\n\n[e21a693a-7a69-450b-b393-27415c26a016]\ndescription = \"input base is zero\"\n\n[54a23be5-d99e-41cc-88e0-a650ffe5fcc2]\ndescription = \"input base is negative\"\n\n[9eccf60c-dcc9-407b-95d8-c37b8be56bb6]\ndescription = \"negative digit\"\n\n[232fa4a5-e761-4939-ba0c-ed046cd0676a]\ndescription = \"invalid positive digit\"\n\n[14238f95-45da-41dc-95ce-18f860b30ad3]\ndescription = \"output base is one\"\n\n[73dac367-da5c-4a37-95fe-c87fad0a4047]\ndescription = \"output base is zero\"\n\n[13f81f42-ff53-4e24-89d9-37603a48ebd9]\ndescription = \"output base is negative\"\n\n[0e6c895d-8a5d-4868-a345-309d094cfe8d]\ndescription = \"both bases are negative\"\n"
  },
  {
    "path": "exercises/practice/all-your-base/.meta/version",
    "content": "2.3.0\n"
  },
  {
    "path": "exercises/practice/all-your-base/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/all-your-base/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/all-your-base/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/all-your-base/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/all-your-base/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/all-your-base/src/main/kotlin/BaseConverter.kt",
    "content": "class BaseConverter {\n    // TODO: implement proper constructor to complete the task\n\n    fun convertToBase(newBase: Int): IntArray {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/all-your-base/src/test/kotlin/BaseConverterTest.kt",
    "content": "import org.junit.Assert.assertArrayEquals\nimport org.junit.Ignore\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.rules.ExpectedException\nimport java.util.*\n\nclass BaseConverterTest {\n\n    /*\n     * See https://github.com/junit-team/junit4/wiki/Rules for information on JUnit Rules in general and\n     * ExpectedExceptions in particular.\n     */\n    @Rule @JvmField\n    var expectedException: ExpectedException = ExpectedException.none()\n\n    @Test\n    fun testSingleBitOneToDecimal() {\n        val baseConverter = BaseConverter(2, intArrayOf(1))\n\n        val expectedDigits = intArrayOf(1)\n        val actualDigits = baseConverter.convertToBase(10)\n\n        assertArrayEquals(\n            \"Expected digits: ${Arrays.toString(expectedDigits)} but found digits: ${Arrays.toString(actualDigits)}\",\n            expectedDigits,\n            actualDigits)\n    }\n\n    @Ignore\n    @Test\n    fun testBinaryToSingleDecimal() {\n        val baseConverter = BaseConverter(2, intArrayOf(1, 0, 1))\n\n        val expectedDigits = intArrayOf(5)\n        val actualDigits = baseConverter.convertToBase(10)\n\n        assertArrayEquals(\n            \"Expected digits: ${Arrays.toString(expectedDigits)} but found digits: ${Arrays.toString(actualDigits)}\",\n            expectedDigits,\n            actualDigits)\n    }\n\n    @Ignore\n    @Test\n    fun testSingleDecimalToBinary() {\n        val baseConverter = BaseConverter(10, intArrayOf(5))\n\n        val expectedDigits = intArrayOf(1, 0, 1)\n        val actualDigits = baseConverter.convertToBase(2)\n\n        assertArrayEquals(\n            \"Expected digits: ${Arrays.toString(expectedDigits)} but found digits: ${Arrays.toString(actualDigits)}\",\n            expectedDigits,\n            actualDigits)\n    }\n\n    @Ignore\n    @Test\n    fun testBinaryToMultipleDecimal() {\n        val baseConverter = BaseConverter(2, intArrayOf(1, 0, 1, 0, 1, 0))\n\n        val expectedDigits = intArrayOf(4, 2)\n        val actualDigits = baseConverter.convertToBase(10)\n\n        assertArrayEquals(\n            \"Expected digits: ${Arrays.toString(expectedDigits)} but found digits: ${Arrays.toString(actualDigits)}\",\n            expectedDigits,\n            actualDigits)\n    }\n\n    @Ignore\n    @Test\n    fun testDecimalToBinary() {\n        val baseConverter = BaseConverter(10, intArrayOf(4, 2))\n\n        val expectedDigits = intArrayOf(1, 0, 1, 0, 1, 0)\n        val actualDigits = baseConverter.convertToBase(2)\n\n        assertArrayEquals(\n            \"Expected digits: ${Arrays.toString(expectedDigits)} but found digits: ${Arrays.toString(actualDigits)}\",\n            expectedDigits,\n            actualDigits)\n    }\n\n    @Ignore\n    @Test\n    fun testTrinaryToHexadecimal() {\n        val baseConverter = BaseConverter(3, intArrayOf(1, 1, 2, 0))\n\n        val expectedDigits = intArrayOf(2, 10)\n        val actualDigits = baseConverter.convertToBase(16)\n\n        assertArrayEquals(\n            \"Expected digits: ${Arrays.toString(expectedDigits)} but found digits: ${Arrays.toString(actualDigits)}\",\n            expectedDigits,\n            actualDigits)\n    }\n\n    @Ignore\n    @Test\n    fun testHexadecimalToTrinary() {\n        val baseConverter = BaseConverter(16, intArrayOf(2, 10))\n\n        val expectedDigits = intArrayOf(1, 1, 2, 0)\n        val actualDigits = baseConverter.convertToBase(3)\n\n        assertArrayEquals(\n            \"Expected digits: ${Arrays.toString(expectedDigits)} but found digits: ${Arrays.toString(actualDigits)}\",\n            expectedDigits,\n            actualDigits)\n    }\n\n    @Ignore\n    @Test\n    fun test15BitInteger() {\n        val baseConverter = BaseConverter(97, intArrayOf(3, 46, 60))\n\n        val expectedDigits = intArrayOf(6, 10, 45)\n        val actualDigits = baseConverter.convertToBase(73)\n\n        assertArrayEquals(\n            \"Expected digits: ${Arrays.toString(expectedDigits)} but found digits: ${Arrays.toString(actualDigits)}\",\n            expectedDigits,\n            actualDigits)\n    }\n\n    @Ignore\n    @Test\n    fun testEmptyDigits() {\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"You must supply at least one digit.\")\n\n        BaseConverter(2, intArrayOf())\n    }\n\n    @Ignore\n    @Test\n    fun testSingleZero() {\n        val baseConverter = BaseConverter(10, intArrayOf(0))\n\n        val expectedDigits = intArrayOf(0)\n        val actualDigits = baseConverter.convertToBase(2)\n\n        assertArrayEquals(\n            \"Expected digits: ${Arrays.toString(expectedDigits)} but found digits: ${Arrays.toString(actualDigits)}\",\n            expectedDigits,\n            actualDigits)\n    }\n\n    @Ignore\n    @Test\n    fun testMultipleZeros() {\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"Digits may not contain leading zeros.\")\n\n        BaseConverter(10, intArrayOf(0, 0, 0))\n    }\n\n    @Ignore\n    @Test\n    fun testLeadingZeros() {\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"Digits may not contain leading zeros.\")\n\n        BaseConverter(7, intArrayOf(0, 6, 0))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstBaseIsOne() {\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"Bases must be at least 2.\")\n\n        BaseConverter(1, intArrayOf(0))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstBaseIsZero() {\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"Bases must be at least 2.\")\n\n        BaseConverter(0, intArrayOf())\n    }\n\n    @Ignore\n    @Test\n    fun testFirstBaseIsNegative() {\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"Bases must be at least 2.\")\n\n        BaseConverter(-2, intArrayOf(1))\n    }\n\n    @Ignore\n    @Test\n    fun testNegativeDigit() {\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"Digits may not be negative.\")\n\n        BaseConverter(2, intArrayOf(1, -1, 1, 0, 1, 0))\n    }\n\n    @Ignore\n    @Test\n    fun testInvalidPositiveDigit() {\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"All digits must be strictly less than the base.\")\n\n        BaseConverter(2, intArrayOf(1, 2, 1, 0, 1, 0))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondBaseIsOne() {\n        val baseConverter = BaseConverter(2, intArrayOf(1, 0, 1, 0, 1, 0))\n\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"Bases must be at least 2.\")\n\n        baseConverter.convertToBase(1)\n    }\n\n    @Ignore\n    @Test\n    fun testSecondBaseIsZero() {\n        val baseConverter = BaseConverter(2, intArrayOf(1, 0, 1, 0, 1, 0))\n\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"Bases must be at least 2.\")\n\n        baseConverter.convertToBase(0)\n    }\n\n    @Ignore\n    @Test\n    fun testSecondBaseIsNegative() {\n        val baseConverter = BaseConverter(2, intArrayOf(1))\n\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"Bases must be at least 2.\")\n\n        baseConverter.convertToBase(-7)\n    }\n}\n"
  },
  {
    "path": "exercises/practice/allergies/.docs/instructions.md",
    "content": "# Instructions\n\nGiven a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies.\n\nAn allergy test produces a single numeric score which contains the information about all the allergies the person has (that they were tested for).\n\nThe list of items (and their value) that were tested are:\n\n- eggs (1)\n- peanuts (2)\n- shellfish (4)\n- strawberries (8)\n- tomatoes (16)\n- chocolate (32)\n- pollen (64)\n- cats (128)\n\nSo if Tom is allergic to peanuts and chocolate, he gets a score of 34.\n\nNow, given just that score of 34, your program should be able to say:\n\n- Whether Tom is allergic to any one of those allergens listed above.\n- All the allergens Tom is allergic to.\n\nNote: a given score may include allergens **not** listed above (i.e. allergens that score 256, 512, 1024, etc.).\nYour program should ignore those components of the score.\nFor example, if the allergy score is 257, your program should only report the eggs (1) allergy.\n"
  },
  {
    "path": "exercises/practice/allergies/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Allergies.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/AllergiesTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Allergies.kt\"\n    ]\n  },\n  \"blurb\": \"Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies.\",\n  \"source\": \"Exercise by the JumpstartLab team for students at The Turing School of Software and Design.\",\n  \"source_url\": \"https://turing.edu\"\n}\n"
  },
  {
    "path": "exercises/practice/allergies/.meta/src/reference/kotlin/Allergen.kt",
    "content": "enum class Allergen(val score: Int) {\n    EGGS(1),\n    PEANUTS(2),\n    SHELLFISH(4),\n    STRAWBERRIES(8),\n    TOMATOES(16),\n    CHOCOLATE(32),\n    POLLEN(64),\n    CATS(128)\n}\n"
  },
  {
    "path": "exercises/practice/allergies/.meta/src/reference/kotlin/Allergies.kt",
    "content": "class Allergies(val score: Int) {\n\n    fun getList(): List<Allergen> = Allergen.values().filter { isAllergicTo(it) }\n\n    fun isAllergicTo(allergen: Allergen) = (score and allergen.score) == allergen.score\n}\n"
  },
  {
    "path": "exercises/practice/allergies/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# not allergic to anything\n\"17fc7296-2440-4ac4-ad7b-d07c321bc5a0\" = true\n\n# allergic only to eggs\n\"07ced27b-1da5-4c2e-8ae2-cb2791437546\" = true\n\n# allergic to eggs and something else\n\"5035b954-b6fa-4b9b-a487-dae69d8c5f96\" = true\n\n# allergic to something, but not eggs\n\"64a6a83a-5723-4b5b-a896-663307403310\" = true\n\n# allergic to everything\n\"90c8f484-456b-41c4-82ba-2d08d93231c6\" = true\n\n# not allergic to anything\n\"d266a59a-fccc-413b-ac53-d57cb1f0db9d\" = true\n\n# allergic only to peanuts\n\"ea210a98-860d-46b2-a5bf-50d8995b3f2a\" = true\n\n# allergic to peanuts and something else\n\"eac69ae9-8d14-4291-ac4b-7fd2c73d3a5b\" = true\n\n# allergic to something, but not peanuts\n\"9152058c-ce39-4b16-9b1d-283ec6d25085\" = true\n\n# allergic to everything\n\"d2d71fd8-63d5-40f9-a627-fbdaf88caeab\" = true\n\n# not allergic to anything\n\"b948b0a1-cbf7-4b28-a244-73ff56687c80\" = true\n\n# allergic only to shellfish\n\"9ce9a6f3-53e9-4923-85e0-73019047c567\" = true\n\n# allergic to shellfish and something else\n\"b272fca5-57ba-4b00-bd0c-43a737ab2131\" = true\n\n# allergic to something, but not shellfish\n\"21ef8e17-c227-494e-8e78-470a1c59c3d8\" = true\n\n# allergic to everything\n\"cc789c19-2b5e-4c67-b146-625dc8cfa34e\" = true\n\n# not allergic to anything\n\"651bde0a-2a74-46c4-ab55-02a0906ca2f5\" = true\n\n# allergic only to strawberries\n\"b649a750-9703-4f5f-b7f7-91da2c160ece\" = true\n\n# allergic to strawberries and something else\n\"50f5f8f3-3bac-47e6-8dba-2d94470a4bc6\" = true\n\n# allergic to something, but not strawberries\n\"23dd6952-88c9-48d7-a7d5-5d0343deb18d\" = true\n\n# allergic to everything\n\"74afaae2-13b6-43a2-837a-286cd42e7d7e\" = true\n\n# not allergic to anything\n\"c49a91ef-6252-415e-907e-a9d26ef61723\" = true\n\n# allergic only to tomatoes\n\"b69c5131-b7d0-41ad-a32c-e1b2cc632df8\" = true\n\n# allergic to tomatoes and something else\n\"1ca50eb1-f042-4ccf-9050-341521b929ec\" = true\n\n# allergic to something, but not tomatoes\n\"e9846baa-456b-4eff-8025-034b9f77bd8e\" = true\n\n# allergic to everything\n\"b2414f01-f3ad-4965-8391-e65f54dad35f\" = true\n\n# not allergic to anything\n\"978467ab-bda4-49f7-b004-1d011ead947c\" = true\n\n# allergic only to chocolate\n\"59cf4e49-06ea-4139-a2c1-d7aad28f8cbc\" = true\n\n# allergic to chocolate and something else\n\"b0a7c07b-2db7-4f73-a180-565e07040ef1\" = true\n\n# allergic to something, but not chocolate\n\"f5506893-f1ae-482a-b516-7532ba5ca9d2\" = true\n\n# allergic to everything\n\"02debb3d-d7e2-4376-a26b-3c974b6595c6\" = true\n\n# not allergic to anything\n\"17f4a42b-c91e-41b8-8a76-4797886c2d96\" = true\n\n# allergic only to pollen\n\"7696eba7-1837-4488-882a-14b7b4e3e399\" = true\n\n# allergic to pollen and something else\n\"9a49aec5-fa1f-405d-889e-4dfc420db2b6\" = true\n\n# allergic to something, but not pollen\n\"3cb8e79f-d108-4712-b620-aa146b1954a9\" = true\n\n# allergic to everything\n\"1dc3fe57-7c68-4043-9d51-5457128744b2\" = true\n\n# not allergic to anything\n\"d3f523d6-3d50-419b-a222-d4dfd62ce314\" = true\n\n# allergic only to cats\n\"eba541c3-c886-42d3-baef-c048cb7fcd8f\" = true\n\n# allergic to cats and something else\n\"ba718376-26e0-40b7-bbbe-060287637ea5\" = true\n\n# allergic to something, but not cats\n\"3c6dbf4a-5277-436f-8b88-15a206f2d6c4\" = true\n\n# allergic to everything\n\"1faabb05-2b98-4995-9046-d83e4a48a7c1\" = true\n\n# no allergies\n\"f9c1b8e7-7dc5-4887-aa93-cebdcc29dd8f\" = true\n\n# just eggs\n\"9e1a4364-09a6-4d94-990f-541a94a4c1e8\" = true\n\n# just peanuts\n\"8851c973-805e-4283-9e01-d0c0da0e4695\" = true\n\n# just strawberries\n\"2c8943cb-005e-435f-ae11-3e8fb558ea98\" = true\n\n# eggs and peanuts\n\"6fa95d26-044c-48a9-8a7b-9ee46ec32c5c\" = true\n\n# more than eggs but not peanuts\n\"19890e22-f63f-4c5c-a9fb-fb6eacddfe8e\" = true\n\n# lots of stuff\n\"4b68f470-067c-44e4-889f-c9fe28917d2f\" = true\n\n# everything\n\"0881b7c5-9efa-4530-91bd-68370d054bc7\" = true\n\n# no allergen score parts\n\"12ce86de-b347-42a0-ab7c-2e0570f0c65b\" = true\n"
  },
  {
    "path": "exercises/practice/allergies/.meta/version",
    "content": "2.0.0\n"
  },
  {
    "path": "exercises/practice/allergies/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/allergies/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/allergies/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/allergies/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/allergies/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/allergies/src/main/kotlin/Allergen.kt",
    "content": "enum class Allergen(val score: Int) {\n    EGGS(1),\n    PEANUTS(2),\n    SHELLFISH(4),\n    STRAWBERRIES(8),\n    TOMATOES(16),\n    CHOCOLATE(32),\n    POLLEN(64),\n    CATS(128)\n}\n"
  },
  {
    "path": "exercises/practice/allergies/src/main/kotlin/Allergies.kt",
    "content": "class Allergies {\n    // TODO: implement proper constructor to complete the task\n\n    fun getList(): List<Allergen> {\n        TODO(\"Implement the function to complete the task\")\n    }\n\n    fun isAllergicTo(allergen: Allergen) {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/allergies/src/test/kotlin/AllergiesTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\nimport kotlin.test.assertFalse\nimport kotlin.test.assertTrue\n\nclass AllergiesTest {\n    @Test\n    fun `eggs - not allergic to anything`() = assertIsNotAllergic(0, Allergen.EGGS)\n\n    @Ignore\n    @Test\n    fun `eggs - allergic only to eggs`() = assertIsAllergic(1, Allergen.EGGS)\n\n    @Ignore\n    @Test\n    fun `eggs - allergic to eggs and something else`() = assertIsAllergic(3, Allergen.EGGS)\n\n    @Ignore\n    @Test\n    fun `eggs - allergic to something, but not eggs`() = assertIsNotAllergic(2, Allergen.EGGS)\n\n    @Ignore\n    @Test\n    fun `eggs - allergic to everything`() = assertIsAllergic(255, Allergen.EGGS)\n\n    @Ignore\n    @Test\n    fun `peanuts - not allergic to anything`() = assertIsNotAllergic(0, Allergen.PEANUTS)\n\n    @Ignore\n    @Test\n    fun `peanuts - allergic only to peanuts`() = assertIsAllergic(2, Allergen.PEANUTS)\n\n    @Ignore\n    @Test\n    fun `peanuts - allergic to peanuts and something else`() = assertIsAllergic(7, Allergen.PEANUTS)\n\n    @Ignore\n    @Test\n    fun `peanuts - allergic to something, but not peanuts`() = assertIsNotAllergic(5, Allergen.PEANUTS)\n\n    @Ignore\n    @Test\n    fun `peanuts - allergic to everything`() = assertIsAllergic(255, Allergen.PEANUTS)\n\n    @Ignore\n    @Test\n    fun `shellfish - not allergic to anything`() = assertIsNotAllergic(0, Allergen.SHELLFISH)\n\n    @Ignore\n    @Test\n    fun `shellfish - allergic only to shellfish`() = assertIsAllergic(4, Allergen.SHELLFISH)\n\n    @Ignore\n    @Test\n    fun `shellfish - allergic to shellfish and something else`() = assertIsAllergic(14, Allergen.SHELLFISH)\n\n    @Ignore\n    @Test\n    fun `shellfish - allergic to something, but not shellfish`() = assertIsNotAllergic(10, Allergen.SHELLFISH)\n\n    @Ignore\n    @Test\n    fun `shellfish - allergic to everything`() = assertIsAllergic(255, Allergen.SHELLFISH)\n\n    @Ignore\n    @Test\n    fun `strawberries - not allergic to anything`() = assertIsNotAllergic(0, Allergen.STRAWBERRIES)\n\n    @Ignore\n    @Test\n    fun `strawberries - allergic only to strawberries`() = assertIsAllergic(8, Allergen.STRAWBERRIES)\n\n    @Ignore\n    @Test\n    fun `strawberries - allergic to strawberries and something else`() = assertIsAllergic(28, Allergen.STRAWBERRIES)\n\n    @Ignore\n    @Test\n    fun `strawberries - allergic to something, but not strawberries`() = assertIsNotAllergic(20, Allergen.STRAWBERRIES)\n\n    @Ignore\n    @Test\n    fun `strawberries - allergic to everything`() = assertIsAllergic(255, Allergen.STRAWBERRIES)\n\n    @Ignore\n    @Test\n    fun `tomatoes - not allergic to anything`() = assertIsNotAllergic(0, Allergen.TOMATOES)\n\n    @Ignore\n    @Test\n    fun `tomatoes - allergic only to tomatoes`() = assertIsAllergic(16, Allergen.TOMATOES)\n\n    @Ignore\n    @Test\n    fun `tomatoes - allergic to tomatoes and something else`() = assertIsAllergic(56, Allergen.TOMATOES)\n\n    @Ignore\n    @Test\n    fun `tomatoes - allergic to something, but not tomatoes`() = assertIsNotAllergic(40, Allergen.TOMATOES)\n\n    @Ignore\n    @Test\n    fun `tomatoes - allergic to everything`() = assertIsAllergic(255, Allergen.TOMATOES)\n\n    @Ignore\n    @Test\n    fun `chocolate - not allergic to anything`() = assertIsNotAllergic(0, Allergen.CHOCOLATE)\n\n    @Ignore\n    @Test\n    fun `chocolate - allergic only to chocolate`() = assertIsAllergic(32, Allergen.CHOCOLATE)\n\n    @Ignore\n    @Test\n    fun `chocolate - allergic to chocolate and something else`() = assertIsAllergic(112, Allergen.CHOCOLATE)\n\n    @Ignore\n    @Test\n    fun `chocolate - allergic to something, but not chocolate`() = assertIsNotAllergic(80, Allergen.CHOCOLATE)\n\n    @Ignore\n    @Test\n    fun `chocolate - allergic to everything`() = assertIsAllergic(255, Allergen.CHOCOLATE)\n\n    @Ignore\n    @Test\n    fun `pollen - not allergic to anything`() = assertIsNotAllergic(0, Allergen.POLLEN)\n\n    @Ignore\n    @Test\n    fun `pollen - allergic only to pollen`() = assertIsAllergic(64, Allergen.POLLEN)\n\n    @Ignore\n    @Test\n    fun `pollen - allergic to pollen and something else`() = assertIsAllergic(224, Allergen.POLLEN)\n\n    @Ignore\n    @Test\n    fun `pollen - allergic to something, but not pollen`() = assertIsNotAllergic(160, Allergen.POLLEN)\n\n    @Ignore\n    @Test\n    fun `pollen - allergic to everything`() = assertIsAllergic(255, Allergen.POLLEN)\n\n    @Ignore\n    @Test\n    fun `cats - not allergic to anything`() = assertIsNotAllergic(0, Allergen.CATS)\n\n    @Ignore\n    @Test\n    fun `cats - allergic only to cats`() = assertIsAllergic(128, Allergen.CATS)\n\n    @Ignore\n    @Test\n    fun `cats - allergic to cats and something else`() = assertIsAllergic(192, Allergen.CATS)\n\n    @Ignore\n    @Test\n    fun `cats - allergic to something, but not cats`() = assertIsNotAllergic(64, Allergen.CATS)\n\n    @Ignore\n    @Test\n    fun `cats - allergic to everything`() = assertIsAllergic(255, Allergen.CATS)\n\n    @Ignore\n    @Test\n    fun `list - no allergies`() = assertAllergens(0, emptyList())\n\n    @Ignore\n    @Test\n    fun `list - just eggs`() = assertAllergens(\n            1,\n            listOf(Allergen.EGGS))\n\n    @Ignore\n    @Test\n    fun `list - just peanuts`() = assertAllergens(\n            2,\n            listOf(Allergen.PEANUTS))\n\n    @Ignore\n    @Test\n    fun `list - eggs and peanuts`() = assertAllergens(\n            3,\n            listOf(Allergen.EGGS, Allergen.PEANUTS))\n\n    @Ignore\n    @Test\n    fun `list - more than eggs but not peanuts`() = assertAllergens(\n            5,\n            listOf(Allergen.EGGS, Allergen.SHELLFISH))\n\n    @Ignore\n    @Test\n    fun `list - lots of stuff`() = assertAllergens(\n            248,\n            listOf(Allergen.STRAWBERRIES, Allergen.TOMATOES, Allergen.CHOCOLATE, Allergen.POLLEN, Allergen.CATS))\n\n    @Ignore\n    @Test\n    fun `list - everything`() = assertAllergens(\n            255,\n            Allergen.values().toList())\n\n    @Ignore\n    @Test\n    fun `list - no allergen score parts`() = assertAllergens(\n            509,\n            Allergen.values().toList() - Allergen.PEANUTS)\n}\n\nprivate fun assertIsAllergic(score: Int, allergen: Allergen) = assertTrue(Allergies(score).isAllergicTo(allergen))\n\nprivate fun assertIsNotAllergic(score: Int, allergen: Allergen) = assertFalse(Allergies(score).isAllergicTo(allergen))\n\nprivate fun assertAllergens(score: Int, allergens: List<Allergen>) = assertEquals(allergens, Allergies(score).getList())\n"
  },
  {
    "path": "exercises/practice/anagram/.docs/instructions.append.md",
    "content": "# Instructions Append\n\nThe anagrams can be returned in any order.\n"
  },
  {
    "path": "exercises/practice/anagram/.docs/instructions.md",
    "content": "# Instructions\n\nGiven a target word and one or more candidate words, your task is to find the candidates that are anagrams of the target.\n\nAn anagram is a rearrangement of letters to form a new word: for example `\"owns\"` is an anagram of `\"snow\"`.\nA word is _not_ its own anagram: for example, `\"stop\"` is not an anagram of `\"stop\"`.\n\nThe target word and candidate words are made up of one or more ASCII alphabetic characters (`A`-`Z` and `a`-`z`).\nLowercase and uppercase characters are equivalent: for example, `\"PoTS\"` is an anagram of `\"sTOp\"`, but `\"StoP\"` is not an anagram of `\"sTOp\"`.\nThe words you need to find should be taken from the candidate words, using the same letter case.\n\nGiven the target `\"stone\"` and the candidate words `\"stone\"`, `\"tones\"`, `\"banana\"`, `\"tons\"`, `\"notes\"`, and `\"Seton\"`, the anagram words you need to find are `\"tones\"`, `\"notes\"`, and `\"Seton\"`.\n"
  },
  {
    "path": "exercises/practice/anagram/.docs/introduction.md",
    "content": "# Introduction\n\nAt a garage sale, you find a lovely vintage typewriter at a bargain price!\nExcitedly, you rush home, insert a sheet of paper, and start typing away.\nHowever, your excitement wanes when you examine the output: all words are garbled!\nFor example, it prints \"stop\" instead of \"post\" and \"least\" instead of \"stale.\"\nCarefully, you try again, but now it prints \"spot\" and \"slate.\"\nAfter some experimentation, you find there is a random delay before each letter is printed, which messes up the order.\nYou now understand why they sold it for so little money!\n\nYou realize this quirk allows you to generate anagrams, which are words formed by rearranging the letters of another word.\nPleased with your finding, you spend the rest of the day generating hundreds of anagrams.\n"
  },
  {
    "path": "exercises/practice/anagram/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"sup95\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Anagram.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/AnagramTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Anagram.kt\"\n    ]\n  },\n  \"blurb\": \"Given a word and a list of possible anagrams, select the correct sublist.\",\n  \"source\": \"Inspired by the Extreme Startup game\",\n  \"source_url\": \"https://github.com/rchatley/extreme_startup\"\n}\n"
  },
  {
    "path": "exercises/practice/anagram/.meta/src/reference/kotlin/Anagram.kt",
    "content": "class Anagram(private val word: String) {\n\n    fun match(anagrams: Collection<String>) =\n            anagrams.filter { containSameChars(it.lowercase()) }\n                    .filterNot { it.equals(word, ignoreCase = true) }\n                    .toSet()\n\n    private fun containSameChars(candidate: String) =\n            candidate.lowercase().toCharArray().sorted() == word.lowercase().toCharArray().sorted()\n\n}\n"
  },
  {
    "path": "exercises/practice/anagram/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# no matches\n\"dd40c4d2-3c8b-44e5-992a-f42b393ec373\" = true\n\n# detects two anagrams\n\"b3cca662-f50a-489e-ae10-ab8290a09bdc\" = true\n\n# does not detect anagram subsets\n\"a27558ee-9ba0-4552-96b1-ecf665b06556\" = true\n\n# detects anagram\n\"64cd4584-fc15-4781-b633-3d814c4941a4\" = true\n\n# detects three anagrams\n\"99c91beb-838f-4ccd-b123-935139917283\" = true\n\n# detects multiple anagrams with different case\n\"78487770-e258-4e1f-a646-8ece10950d90\" = true\n\n# does not detect non-anagrams with identical checksum\n\"1d0ab8aa-362f-49b7-9902-3d0c668d557b\" = true\n\n# detects anagrams case-insensitively\n\"9e632c0b-c0b1-4804-8cc1-e295dea6d8a8\" = true\n\n# detects anagrams using case-insensitive subject\n\"b248e49f-0905-48d2-9c8d-bd02d8c3e392\" = true\n\n# detects anagrams using case-insensitive possible matches\n\"f367325c-78ec-411c-be76-e79047f4bd54\" = true\n\n# does not detect an anagram if the original word is repeated\n\"7cc195ad-e3c7-44ee-9fd2-d3c344806a2c\" = true\n\n# anagrams must use all letters exactly once\n\"9878a1c9-d6ea-4235-ae51-3ea2befd6842\" = true\n\n# words are not anagrams of themselves (case-insensitive)\n\"85757361-4535-45fd-ac0e-3810d40debc1\" = true\n\n# words other than themselves can be anagrams\n\"a0705568-628c-4b55-9798-82e4acde51ca\" = true\n"
  },
  {
    "path": "exercises/practice/anagram/.meta/version",
    "content": "1.5.0\n"
  },
  {
    "path": "exercises/practice/anagram/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/anagram/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/anagram/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/anagram/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/anagram/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/anagram/src/main/kotlin/Anagram.kt",
    "content": "class Anagram {\n    // TODO: implement proper constructor to complete the task\n\n    fun match(anagrams: Collection<String>): Set<String> {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/anagram/src/test/kotlin/AnagramTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\nimport kotlin.test.assertTrue\n\nclass AnagramTest {\n\n    @Test\n    fun `no matches`() =\n        anagramsOf(\"diaper\")\n            .searchedIn(\"hello\", \"world\", \"zombies\", \"pants\")\n            .shouldBeEmpty()\n\n    @Ignore\n    @Test\n    fun `detects two anagrams`() =\n        anagramsOf(\"master\")\n            .searchedIn(\"stream\", \"pigeon\", \"maters\")\n            .shouldBeOnly(\"maters\", \"stream\")\n\n    @Ignore\n    @Test\n    fun `does not detect anagram subsets`() =\n        anagramsOf(\"good\")\n            .searchedIn(\"dog\", \"goody\")\n            .shouldBeEmpty()\n\n    @Ignore\n    @Test\n    fun `detects anagram`() =\n        anagramsOf(\"listen\")\n            .searchedIn(\"enlists\", \"google\", \"inlets\", \"banana\")\n            .shouldBeOnly(\"inlets\")\n\n    @Ignore\n    @Test\n    fun `detects three anagrams`() =\n        anagramsOf(\"allergy\")\n            .searchedIn(\"gallery\", \"ballerina\", \"regally\", \"clergy\", \"largely\", \"leading\")\n            .shouldBeOnly(\"gallery\", \"largely\", \"regally\")\n\n    @Ignore\n    @Test\n    fun `detects multiple anagrams with different case`() =\n        anagramsOf(\"nose\")\n            .searchedIn(\"Eons\", \"ONES\")\n            .shouldBeOnly(\"Eons\", \"ONES\")\n\n    @Ignore\n    @Test\n    fun `does not detect non-anagrams with identical checksum`() =\n        anagramsOf(\"mass\")\n            .searchedIn(\"last\")\n            .shouldBeEmpty()\n\n    @Ignore\n    @Test\n    fun `detects anagrams case-insensitively`() =\n        anagramsOf(\"Orchestra\")\n            .searchedIn(\"cashregister\", \"Carthorse\", \"radishes\")\n            .shouldBeOnly(\"Carthorse\")\n\n    @Ignore\n    @Test\n    fun `detects anagrams using case-insensitive subject`() =\n        anagramsOf(\"Orchestra\")\n            .searchedIn(\"cashregister\", \"carthorse\", \"radishes\")\n            .shouldBeOnly(\"carthorse\")\n\n    @Ignore\n    @Test\n    fun `detects anagrams using case-insensitive possible matches`() =\n\n        anagramsOf(\"orchestra\")\n            .searchedIn(\"cashregister\", \"Carthorse\", \"radishes\")\n            .shouldBeOnly(\"Carthorse\")\n\n    @Ignore\n    @Test\n    fun `does not detect an anagram if the original word is repeated`() =\n        anagramsOf(\"go\")\n            .searchedIn(\"go Go GO\")\n            .shouldBeEmpty()\n\n    @Ignore\n    @Test\n    fun `anagrams must use all letters exactly once`() =\n        anagramsOf(\"tapper\")\n            .searchedIn(\"patter\")\n            .shouldBeEmpty()\n\n    @Ignore\n    @Test\n    fun `words are not anagrams of themselves (case-insensitive)`() =\n        anagramsOf(\"BANANA\")\n            .searchedIn(\"Banana\")\n            .shouldBeEmpty()\n\n    @Ignore\n    @Test\n    fun `words other than themselves can be anagrams`() =\n        anagramsOf(\"LISTEN\")\n            .searchedIn(\"Listen\", \"Silent\", \"LISTEN\")\n            .shouldBeOnly(\"Silent\")\n}\n\nprivate fun anagramsOf(source: String) = Anagram(source)\nprivate fun Anagram.searchedIn(vararg variants: String) = this.match(setOf(*variants))\nprivate fun Set<String>.shouldBeOnly(vararg expectation: String) = assertEquals(setOf(*expectation), this)\nprivate fun Set<String>.shouldBeEmpty() = assertTrue(this.isEmpty())\n"
  },
  {
    "path": "exercises/practice/armstrong-numbers/.docs/instructions.md",
    "content": "# Instructions\n\nAn [Armstrong number][armstrong-number] is a number that is the sum of its own digits each raised to the power of the number of digits.\n\nFor example:\n\n- 9 is an Armstrong number, because `9 = 9^1 = 9`\n- 10 is _not_ an Armstrong number, because `10 != 1^2 + 0^2 = 1`\n- 153 is an Armstrong number, because: `153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153`\n- 154 is _not_ an Armstrong number, because: `154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190`\n\nWrite some code to determine whether a number is an Armstrong number.\n\n[armstrong-number]: https://en.wikipedia.org/wiki/Narcissistic_number\n"
  },
  {
    "path": "exercises/practice/armstrong-numbers/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/ArmstrongNumber.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ArmstrongNumberTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/ArmstrongNumber.kt\"\n    ]\n  },\n  \"blurb\": \"Determine if a number is an Armstrong number.\",\n  \"source\": \"Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Narcissistic_number\"\n}\n"
  },
  {
    "path": "exercises/practice/armstrong-numbers/.meta/src/reference/kotlin/ArmstrongNumber.kt",
    "content": "import java.math.BigInteger\n\nobject ArmstrongNumber {\n\n    fun check(input: Long): Boolean {\n        val str = input.toString()\n        val inputLength = str.length\n        val calculated = str\n            .map { Character.getNumericValue(it) } // digit character to its numeric (not ASCII!) value\n            .sumOf { BigInteger.valueOf(it.toLong()).pow(inputLength).toLong() } // calculate digit^inputLength\n\n        return input == calculated\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/armstrong-numbers/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# Zero is an Armstrong number\n\"c1ed103c-258d-45b2-be73-d8c6d9580c7b\" = true\n\n# Single digit numbers are Armstrong numbers\n\"579e8f03-9659-4b85-a1a2-d64350f6b17a\" = true\n\n# There are no 2 digit Armstrong numbers\n\"2d6db9dc-5bf8-4976-a90b-b2c2b9feba60\" = true\n\n# Three digit number that is an Armstrong number\n\"509c087f-e327-4113-a7d2-26a4e9d18283\" = true\n\n# Three digit number that is not an Armstrong number\n\"7154547d-c2ce-468d-b214-4cb953b870cf\" = true\n\n# Four digit number that is an Armstrong number\n\"6bac5b7b-42e9-4ecb-a8b0-4832229aa103\" = true\n\n# Four digit number that is not an Armstrong number\n\"eed4b331-af80-45b5-a80b-19c9ea444b2e\" = true\n\n# Seven digit number that is an Armstrong number\n\"f971ced7-8d68-4758-aea1-d4194900b864\" = true\n\n# Seven digit number that is not an Armstrong number\n\"7ee45d52-5d35-4fbd-b6f1-5c8cd8a67f18\" = true\n"
  },
  {
    "path": "exercises/practice/armstrong-numbers/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/armstrong-numbers/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/armstrong-numbers/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/armstrong-numbers/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/armstrong-numbers/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/armstrong-numbers/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/armstrong-numbers/src/main/kotlin/ArmstrongNumber.kt",
    "content": "object ArmstrongNumber {\n\n    fun check(input: Int): Boolean {\n        TODO(\"Implement the function to complete the task\")\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/armstrong-numbers/src/test/kotlin/ArmstrongNumberTest.kt",
    "content": "import kotlin.test.Test\nimport kotlin.test.assertTrue\nimport kotlin.test.assertFalse\nimport kotlin.test.Ignore\n\nclass ArmstrongNumberTest {\n\n    @Test\n    fun `zero is an armstrong number`() = assertTrue(ArmstrongNumber.check(0))\n\n    @Ignore\n    @Test\n    fun `single digit numbers are armstrong numbers`() = assertTrue(ArmstrongNumber.check(5))\n\n    @Ignore\n    @Test\n    fun `there are no 2 digit armstrong numbers`() = assertFalse(ArmstrongNumber.check(10))\n\n    @Ignore\n    @Test\n    fun `three digit number that is an armstrong number`() = assertTrue(ArmstrongNumber.check(153))\n\n    @Ignore\n    @Test\n    fun `three digit number that is not an armstrong number`() = assertFalse(ArmstrongNumber.check(100))\n\n    @Ignore\n    @Test\n    fun `four digit number that is an armstrong number`() = assertTrue(ArmstrongNumber.check(9474))\n\n    @Ignore\n    @Test\n    fun `four digit number that is not an armstrong number`() = assertFalse(ArmstrongNumber.check(9475))\n\n    @Ignore\n    @Test\n    fun `seven digit number that is an armstrong number`() = assertTrue(ArmstrongNumber.check(9926315))\n\n    @Ignore\n    @Test\n    fun `seven digit number that is not an armstrong number`() = assertFalse(ArmstrongNumber.check(9926314))\n}\n"
  },
  {
    "path": "exercises/practice/atbash-cipher/.docs/instructions.md",
    "content": "# Instructions\n\nCreate an implementation of the Atbash cipher, an ancient encryption system created in the Middle East.\n\nThe Atbash cipher is a simple substitution cipher that relies on transposing all the letters in the alphabet such that the resulting alphabet is backwards.\nThe first letter is replaced with the last letter, the second with the second-last, and so on.\n\nAn Atbash cipher for the Latin alphabet would be as follows:\n\n```text\nPlain:  abcdefghijklmnopqrstuvwxyz\nCipher: zyxwvutsrqponmlkjihgfedcba\n```\n\nIt is a very weak cipher because it only has one possible key, and it is a simple mono-alphabetic substitution cipher.\nHowever, this may not have been an issue in the cipher's time.\n\nCiphertext is written out in groups of fixed length, the traditional group size being 5 letters, leaving numbers unchanged, and punctuation is excluded.\nThis is to make it harder to guess things based on word boundaries.\nAll text will be encoded as lowercase letters.\n\n## Examples\n\n- Encoding `test` gives `gvhg`\n- Encoding `x123 yes` gives `c123b vh`\n- Decoding `gvhg` gives `test`\n- Decoding `gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt` gives `thequickbrownfoxjumpsoverthelazydog`\n"
  },
  {
    "path": "exercises/practice/atbash-cipher/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"kytrinyx\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Atbash.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/AtbashTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Atbash.kt\"\n    ]\n  },\n  \"blurb\": \"Create an implementation of the Atbash cipher, an ancient encryption system created in the Middle East.\",\n  \"source\": \"Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Atbash\"\n}\n"
  },
  {
    "path": "exercises/practice/atbash-cipher/.meta/src/reference/kotlin/Atbash.kt",
    "content": "object Atbash {\n    private const val GROUP_SIZE = 5\n\n    fun encode(s: String): String = cipherSubstitution(s).mapIndexed { index, char -> char + groupFinalizer(index) }.joinToString(\"\").trimEnd()\n\n    fun decode(s: String): String = cipherSubstitution(s)\n\n    private fun cipherSubstitution(s: String): String = s.fold(\"\") { accum, char -> accum + substitute(char) }\n\n    private fun substitute(c: Char): String {\n        return when {\n            c.isDigit() -> c.toString()\n            c.isLetter() -> ('a' + ('z' - c.lowercaseChar())).toString()\n            else -> \"\"\n        }\n    }\n\n    private fun groupFinalizer(index: Int): String = if ((index + 1) % GROUP_SIZE == 0) \" \" else \"\"\n\n\n\n}\n"
  },
  {
    "path": "exercises/practice/atbash-cipher/.meta/tests.toml",
    "content": "# This is an auto-generated file.\n#\n# Regenerating this file via `configlet sync` will:\n# - Recreate every `description` key/value pair\n# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications\n# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)\n# - Preserve any other key/value pair\n#\n# As user-added comments (using the # character) will be removed when this file\n# is regenerated, comments can be added via a `comment` key.\n\n[2f47ebe1-eab9-4d6b-b3c6-627562a31c77]\ndescription = \"encode -> encode yes\"\n\n[b4ffe781-ea81-4b74-b268-cc58ba21c739]\ndescription = \"encode -> encode no\"\n\n[10e48927-24ab-4c4d-9d3f-3067724ace00]\ndescription = \"encode -> encode OMG\"\n\n[d59b8bc3-509a-4a9a-834c-6f501b98750b]\ndescription = \"encode -> encode spaces\"\n\n[31d44b11-81b7-4a94-8b43-4af6a2449429]\ndescription = \"encode -> encode mindblowingly\"\n\n[d503361a-1433-48c0-aae0-d41b5baa33ff]\ndescription = \"encode -> encode numbers\"\n\n[79c8a2d5-0772-42d4-b41b-531d0b5da926]\ndescription = \"encode -> encode deep thought\"\n\n[9ca13d23-d32a-4967-a1fd-6100b8742bab]\ndescription = \"encode -> encode all the letters\"\n\n[bb50e087-7fdf-48e7-9223-284fe7e69851]\ndescription = \"decode -> decode exercism\"\n\n[ac021097-cd5d-4717-8907-b0814b9e292c]\ndescription = \"decode -> decode a sentence\"\n\n[18729de3-de74-49b8-b68c-025eaf77f851]\ndescription = \"decode -> decode numbers\"\n\n[0f30325f-f53b-415d-ad3e-a7a4f63de034]\ndescription = \"decode -> decode all the letters\"\n\n[39640287-30c6-4c8c-9bac-9d613d1a5674]\ndescription = \"decode -> decode with too many spaces\"\n\n[b34edf13-34c0-49b5-aa21-0768928000d5]\ndescription = \"decode -> decode with no spaces\"\n"
  },
  {
    "path": "exercises/practice/atbash-cipher/.meta/version",
    "content": "1.2.0\n"
  },
  {
    "path": "exercises/practice/atbash-cipher/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/atbash-cipher/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/atbash-cipher/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/atbash-cipher/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/atbash-cipher/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/atbash-cipher/src/main/kotlin/Atbash.kt",
    "content": "object Atbash {\n\n    fun encode(s: String): String{\n        TODO(\"Implement the function to complete the task\")\n    }\n\n    fun decode(s: String): String{\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/atbash-cipher/src/test/kotlin/AtbashTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport org.junit.experimental.runners.Enclosed\nimport org.junit.runner.RunWith\nimport org.junit.runners.Parameterized\nimport kotlin.test.assertEquals\n\n@RunWith(Enclosed::class)\nclass AtbashTest {\n\n    @RunWith(Parameterized::class)\n    class EncodeTest(val input: String, val expectedOutput: String) {\n\n        companion object {\n            @JvmStatic\n            @Parameterized.Parameters (name = \"{index}: encode({0}) = {1}\")\n            fun data() = listOf(\n                    arrayOf(\"yes\", \"bvh\"),\n                    arrayOf(\"no\", \"ml\"),\n                    arrayOf(\"OMG\", \"lnt\"),\n                    arrayOf(\"O M G\", \"lnt\"),\n                    arrayOf(\"mindblowingly\", \"nrmwy oldrm tob\"),\n                    arrayOf(\"Testing,1 2 3, testing.\", \"gvhgr mt123 gvhgr mt\"),\n                    arrayOf(\"Truth is fiction.\", \"gifgs rhurx grlm\"),\n                    arrayOf(\"The quick brown fox jumps over the lazy dog.\", \"gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt\")\n            )\n        }\n\n        @Test\n        fun test() {\n            assertEquals(expectedOutput, Atbash.encode(input))\n        }\n\n    }\n\n    @RunWith(Parameterized::class)\n    class DecodeTest(val input: String, val expectedOutput: String) {\n\n        companion object {\n            @JvmStatic\n            @Parameterized.Parameters(name = \"{index}: decode({0}) = {1}\")\n            fun data() = listOf(\n                    arrayOf(\"vcvix rhn\", \"exercism\"),\n                    arrayOf(\"zmlyh gzxov rhlug vmzhg vkkrm thglm v\", \"anobstacleisoftenasteppingstone\"),\n                    arrayOf(\"gvhgr mt123 gvhgr mt\", \"testing123testing\"),\n                    arrayOf(\"gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt\", \"thequickbrownfoxjumpsoverthelazydog\"),\n                    arrayOf(\"vc vix    r hn\", \"exercism\"),\n                    arrayOf(\"zmlyhgzxovrhlugvmzhgvkkrmthglmv\", \"anobstacleisoftenasteppingstone\")\n            )\n        }\n\n        @Ignore\n        @Test\n        fun test() {\n            assertEquals(expectedOutput, Atbash.decode(input))\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/bank-account/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to implement bank accounts supporting opening/closing, withdrawals, and deposits of money.\n\nAs 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.\nFor 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.\n\nIt should be possible to close an account; operations against a closed account must fail.\n\n[wikipedia]: https://en.wikipedia.org/wiki/Race_condition#In_software\n"
  },
  {
    "path": "exercises/practice/bank-account/.docs/introduction.md",
    "content": "# Introduction\n\nAfter years of filling out forms and waiting, you've finally acquired your banking license.\nThis means you are now officially eligible to open your own bank, hurray!\n\nYour first priority is to get the IT systems up and running.\nAfter a day of hard work, you can already open and close accounts, as well as handle withdrawals and deposits.\n\nSince you couldn't be bothered writing tests, you invite some friends to help test the system.\nHowever, after just five minutes, one of your friends claims they've lost money!\nWhile you're confident your code is bug-free, you start looking through the logs to investigate.\n\nAh yes, just as you suspected, your friend is at fault!\nThey shared their test credentials with another friend, and together they conspired to make deposits and withdrawals from the same account _in parallel_.\nWho would do such a thing?\n\nWhile 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.\nThus, no parallel banking support, no go-live signal.\nSighing, you create a mental note to work on this tomorrow.\nThis will set your launch date back at _least_ one more day, but well...\n"
  },
  {
    "path": "exercises/practice/bank-account/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"nithia\"\n  ],\n  \"contributors\": [\n    \"araknoid\",\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/BankAccount.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/BankAccountTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/BankAccount.kt\"\n    ]\n  },\n  \"test_runner\": false,\n  \"blurb\": \"Simulate a bank account supporting opening/closing, withdraws, and deposits of money. Watch out for concurrent transactions!\"\n}\n"
  },
  {
    "path": "exercises/practice/bank-account/.meta/src/reference/kotlin/BankAccount.kt",
    "content": "class BankAccount {\n    var balance: Long = 0\n        get() {\n            synchronized(lock) {\n                if (!isOpen) throw IllegalStateException(\"Account is closed\")\n                return field\n            }\n        }\n        private set\n\n    var isOpen = true\n        private set\n\n    fun adjustBalance(amount: Long) {\n        synchronized(lock) {\n            balance += amount\n        }\n    }\n\n    fun close() {\n        synchronized(lock) {\n            isOpen = false\n        }\n    }\n\n    private val lock = Any()\n}\n"
  },
  {
    "path": "exercises/practice/bank-account/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bank-account/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/bank-account/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/bank-account/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/bank-account/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bank-account/src/main/kotlin/BankAccount.kt",
    "content": "class BankAccount {\n    // TODO: implement read access to 'balance'\n\n    fun adjustBalance(amount: Long){\n        TODO(\"Implement the function to complete the task\")\n    }\n\n    fun close() {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bank-account/src/test/kotlin/BankAccountTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport java.util.*\nimport java.util.concurrent.Executors\nimport java.util.concurrent.TimeUnit\nimport kotlin.test.assertEquals\nimport kotlin.test.assertFailsWith\n\nclass BankAccountTest {\n\n    @Test\n    fun zeroBalanceWhenOpened() {\n        val account = BankAccount()\n        assertEquals(0, account.balance)\n    }\n\n    @Ignore\n    @Test\n    fun sequentialBalanceAdjustments() {\n        val account = BankAccount()\n\n        account.adjustBalance(1000)\n        assertEquals(1000, account.balance)\n\n        account.adjustBalance(-958)\n        assertEquals(42, account.balance)\n    }\n\n    @Ignore\n    @Test\n    fun closedAccountHasNoBalance() {\n        val account = BankAccount()\n        account.close()\n\n        assertFailsWith(IllegalStateException::class) { account.balance }\n    }\n\n    @Ignore\n    @Test\n    fun closedAccountCannotBeAdjusted() {\n        val account = BankAccount()\n        account.close()\n\n        assertFailsWith(IllegalStateException::class) { account.adjustBalance(1000) }\n    }\n\n    @Ignore\n    @Test\n    fun concurrentBalanceAdjustments() {\n        val threads = 100\n        val iterations = 500\n        val random = Random()\n\n        val account = BankAccount()\n\n        val executor = Executors.newFixedThreadPool(8)\n\n        repeat(threads) {\n            executor.submit {\n                repeat(iterations) {\n                    account.adjustBalance(1)\n                    Thread.sleep(random.nextInt(10).toLong())\n                    account.adjustBalance(-1)\n                }\n            }\n        }\n\n        executor.shutdown()\n        executor.awaitTermination(10, TimeUnit.MINUTES)\n\n        assertEquals(0, account.balance)\n    }\n\n}\n\n"
  },
  {
    "path": "exercises/practice/beer-song/.docs/instructions.md",
    "content": "# Instructions\n\nRecite the lyrics to that beloved classic, that field-trip favorite: 99 Bottles of Beer on the Wall.\n\nNote that not all verses are identical.\n\n```text\n99 bottles of beer on the wall, 99 bottles of beer.\nTake one down and pass it around, 98 bottles of beer on the wall.\n\n98 bottles of beer on the wall, 98 bottles of beer.\nTake one down and pass it around, 97 bottles of beer on the wall.\n\n97 bottles of beer on the wall, 97 bottles of beer.\nTake one down and pass it around, 96 bottles of beer on the wall.\n\n96 bottles of beer on the wall, 96 bottles of beer.\nTake one down and pass it around, 95 bottles of beer on the wall.\n\n95 bottles of beer on the wall, 95 bottles of beer.\nTake one down and pass it around, 94 bottles of beer on the wall.\n\n94 bottles of beer on the wall, 94 bottles of beer.\nTake one down and pass it around, 93 bottles of beer on the wall.\n\n93 bottles of beer on the wall, 93 bottles of beer.\nTake one down and pass it around, 92 bottles of beer on the wall.\n\n92 bottles of beer on the wall, 92 bottles of beer.\nTake one down and pass it around, 91 bottles of beer on the wall.\n\n91 bottles of beer on the wall, 91 bottles of beer.\nTake one down and pass it around, 90 bottles of beer on the wall.\n\n90 bottles of beer on the wall, 90 bottles of beer.\nTake one down and pass it around, 89 bottles of beer on the wall.\n\n89 bottles of beer on the wall, 89 bottles of beer.\nTake one down and pass it around, 88 bottles of beer on the wall.\n\n88 bottles of beer on the wall, 88 bottles of beer.\nTake one down and pass it around, 87 bottles of beer on the wall.\n\n87 bottles of beer on the wall, 87 bottles of beer.\nTake one down and pass it around, 86 bottles of beer on the wall.\n\n86 bottles of beer on the wall, 86 bottles of beer.\nTake one down and pass it around, 85 bottles of beer on the wall.\n\n85 bottles of beer on the wall, 85 bottles of beer.\nTake one down and pass it around, 84 bottles of beer on the wall.\n\n84 bottles of beer on the wall, 84 bottles of beer.\nTake one down and pass it around, 83 bottles of beer on the wall.\n\n83 bottles of beer on the wall, 83 bottles of beer.\nTake one down and pass it around, 82 bottles of beer on the wall.\n\n82 bottles of beer on the wall, 82 bottles of beer.\nTake one down and pass it around, 81 bottles of beer on the wall.\n\n81 bottles of beer on the wall, 81 bottles of beer.\nTake one down and pass it around, 80 bottles of beer on the wall.\n\n80 bottles of beer on the wall, 80 bottles of beer.\nTake one down and pass it around, 79 bottles of beer on the wall.\n\n79 bottles of beer on the wall, 79 bottles of beer.\nTake one down and pass it around, 78 bottles of beer on the wall.\n\n78 bottles of beer on the wall, 78 bottles of beer.\nTake one down and pass it around, 77 bottles of beer on the wall.\n\n77 bottles of beer on the wall, 77 bottles of beer.\nTake one down and pass it around, 76 bottles of beer on the wall.\n\n76 bottles of beer on the wall, 76 bottles of beer.\nTake one down and pass it around, 75 bottles of beer on the wall.\n\n75 bottles of beer on the wall, 75 bottles of beer.\nTake one down and pass it around, 74 bottles of beer on the wall.\n\n74 bottles of beer on the wall, 74 bottles of beer.\nTake one down and pass it around, 73 bottles of beer on the wall.\n\n73 bottles of beer on the wall, 73 bottles of beer.\nTake one down and pass it around, 72 bottles of beer on the wall.\n\n72 bottles of beer on the wall, 72 bottles of beer.\nTake one down and pass it around, 71 bottles of beer on the wall.\n\n71 bottles of beer on the wall, 71 bottles of beer.\nTake one down and pass it around, 70 bottles of beer on the wall.\n\n70 bottles of beer on the wall, 70 bottles of beer.\nTake one down and pass it around, 69 bottles of beer on the wall.\n\n69 bottles of beer on the wall, 69 bottles of beer.\nTake one down and pass it around, 68 bottles of beer on the wall.\n\n68 bottles of beer on the wall, 68 bottles of beer.\nTake one down and pass it around, 67 bottles of beer on the wall.\n\n67 bottles of beer on the wall, 67 bottles of beer.\nTake one down and pass it around, 66 bottles of beer on the wall.\n\n66 bottles of beer on the wall, 66 bottles of beer.\nTake one down and pass it around, 65 bottles of beer on the wall.\n\n65 bottles of beer on the wall, 65 bottles of beer.\nTake one down and pass it around, 64 bottles of beer on the wall.\n\n64 bottles of beer on the wall, 64 bottles of beer.\nTake one down and pass it around, 63 bottles of beer on the wall.\n\n63 bottles of beer on the wall, 63 bottles of beer.\nTake one down and pass it around, 62 bottles of beer on the wall.\n\n62 bottles of beer on the wall, 62 bottles of beer.\nTake one down and pass it around, 61 bottles of beer on the wall.\n\n61 bottles of beer on the wall, 61 bottles of beer.\nTake one down and pass it around, 60 bottles of beer on the wall.\n\n60 bottles of beer on the wall, 60 bottles of beer.\nTake one down and pass it around, 59 bottles of beer on the wall.\n\n59 bottles of beer on the wall, 59 bottles of beer.\nTake one down and pass it around, 58 bottles of beer on the wall.\n\n58 bottles of beer on the wall, 58 bottles of beer.\nTake one down and pass it around, 57 bottles of beer on the wall.\n\n57 bottles of beer on the wall, 57 bottles of beer.\nTake one down and pass it around, 56 bottles of beer on the wall.\n\n56 bottles of beer on the wall, 56 bottles of beer.\nTake one down and pass it around, 55 bottles of beer on the wall.\n\n55 bottles of beer on the wall, 55 bottles of beer.\nTake one down and pass it around, 54 bottles of beer on the wall.\n\n54 bottles of beer on the wall, 54 bottles of beer.\nTake one down and pass it around, 53 bottles of beer on the wall.\n\n53 bottles of beer on the wall, 53 bottles of beer.\nTake one down and pass it around, 52 bottles of beer on the wall.\n\n52 bottles of beer on the wall, 52 bottles of beer.\nTake one down and pass it around, 51 bottles of beer on the wall.\n\n51 bottles of beer on the wall, 51 bottles of beer.\nTake one down and pass it around, 50 bottles of beer on the wall.\n\n50 bottles of beer on the wall, 50 bottles of beer.\nTake one down and pass it around, 49 bottles of beer on the wall.\n\n49 bottles of beer on the wall, 49 bottles of beer.\nTake one down and pass it around, 48 bottles of beer on the wall.\n\n48 bottles of beer on the wall, 48 bottles of beer.\nTake one down and pass it around, 47 bottles of beer on the wall.\n\n47 bottles of beer on the wall, 47 bottles of beer.\nTake one down and pass it around, 46 bottles of beer on the wall.\n\n46 bottles of beer on the wall, 46 bottles of beer.\nTake one down and pass it around, 45 bottles of beer on the wall.\n\n45 bottles of beer on the wall, 45 bottles of beer.\nTake one down and pass it around, 44 bottles of beer on the wall.\n\n44 bottles of beer on the wall, 44 bottles of beer.\nTake one down and pass it around, 43 bottles of beer on the wall.\n\n43 bottles of beer on the wall, 43 bottles of beer.\nTake one down and pass it around, 42 bottles of beer on the wall.\n\n42 bottles of beer on the wall, 42 bottles of beer.\nTake one down and pass it around, 41 bottles of beer on the wall.\n\n41 bottles of beer on the wall, 41 bottles of beer.\nTake one down and pass it around, 40 bottles of beer on the wall.\n\n40 bottles of beer on the wall, 40 bottles of beer.\nTake one down and pass it around, 39 bottles of beer on the wall.\n\n39 bottles of beer on the wall, 39 bottles of beer.\nTake one down and pass it around, 38 bottles of beer on the wall.\n\n38 bottles of beer on the wall, 38 bottles of beer.\nTake one down and pass it around, 37 bottles of beer on the wall.\n\n37 bottles of beer on the wall, 37 bottles of beer.\nTake one down and pass it around, 36 bottles of beer on the wall.\n\n36 bottles of beer on the wall, 36 bottles of beer.\nTake one down and pass it around, 35 bottles of beer on the wall.\n\n35 bottles of beer on the wall, 35 bottles of beer.\nTake one down and pass it around, 34 bottles of beer on the wall.\n\n34 bottles of beer on the wall, 34 bottles of beer.\nTake one down and pass it around, 33 bottles of beer on the wall.\n\n33 bottles of beer on the wall, 33 bottles of beer.\nTake one down and pass it around, 32 bottles of beer on the wall.\n\n32 bottles of beer on the wall, 32 bottles of beer.\nTake one down and pass it around, 31 bottles of beer on the wall.\n\n31 bottles of beer on the wall, 31 bottles of beer.\nTake one down and pass it around, 30 bottles of beer on the wall.\n\n30 bottles of beer on the wall, 30 bottles of beer.\nTake one down and pass it around, 29 bottles of beer on the wall.\n\n29 bottles of beer on the wall, 29 bottles of beer.\nTake one down and pass it around, 28 bottles of beer on the wall.\n\n28 bottles of beer on the wall, 28 bottles of beer.\nTake one down and pass it around, 27 bottles of beer on the wall.\n\n27 bottles of beer on the wall, 27 bottles of beer.\nTake one down and pass it around, 26 bottles of beer on the wall.\n\n26 bottles of beer on the wall, 26 bottles of beer.\nTake one down and pass it around, 25 bottles of beer on the wall.\n\n25 bottles of beer on the wall, 25 bottles of beer.\nTake one down and pass it around, 24 bottles of beer on the wall.\n\n24 bottles of beer on the wall, 24 bottles of beer.\nTake one down and pass it around, 23 bottles of beer on the wall.\n\n23 bottles of beer on the wall, 23 bottles of beer.\nTake one down and pass it around, 22 bottles of beer on the wall.\n\n22 bottles of beer on the wall, 22 bottles of beer.\nTake one down and pass it around, 21 bottles of beer on the wall.\n\n21 bottles of beer on the wall, 21 bottles of beer.\nTake one down and pass it around, 20 bottles of beer on the wall.\n\n20 bottles of beer on the wall, 20 bottles of beer.\nTake one down and pass it around, 19 bottles of beer on the wall.\n\n19 bottles of beer on the wall, 19 bottles of beer.\nTake one down and pass it around, 18 bottles of beer on the wall.\n\n18 bottles of beer on the wall, 18 bottles of beer.\nTake one down and pass it around, 17 bottles of beer on the wall.\n\n17 bottles of beer on the wall, 17 bottles of beer.\nTake one down and pass it around, 16 bottles of beer on the wall.\n\n16 bottles of beer on the wall, 16 bottles of beer.\nTake one down and pass it around, 15 bottles of beer on the wall.\n\n15 bottles of beer on the wall, 15 bottles of beer.\nTake one down and pass it around, 14 bottles of beer on the wall.\n\n14 bottles of beer on the wall, 14 bottles of beer.\nTake one down and pass it around, 13 bottles of beer on the wall.\n\n13 bottles of beer on the wall, 13 bottles of beer.\nTake one down and pass it around, 12 bottles of beer on the wall.\n\n12 bottles of beer on the wall, 12 bottles of beer.\nTake one down and pass it around, 11 bottles of beer on the wall.\n\n11 bottles of beer on the wall, 11 bottles of beer.\nTake one down and pass it around, 10 bottles of beer on the wall.\n\n10 bottles of beer on the wall, 10 bottles of beer.\nTake one down and pass it around, 9 bottles of beer on the wall.\n\n9 bottles of beer on the wall, 9 bottles of beer.\nTake one down and pass it around, 8 bottles of beer on the wall.\n\n8 bottles of beer on the wall, 8 bottles of beer.\nTake one down and pass it around, 7 bottles of beer on the wall.\n\n7 bottles of beer on the wall, 7 bottles of beer.\nTake one down and pass it around, 6 bottles of beer on the wall.\n\n6 bottles of beer on the wall, 6 bottles of beer.\nTake one down and pass it around, 5 bottles of beer on the wall.\n\n5 bottles of beer on the wall, 5 bottles of beer.\nTake one down and pass it around, 4 bottles of beer on the wall.\n\n4 bottles of beer on the wall, 4 bottles of beer.\nTake one down and pass it around, 3 bottles of beer on the wall.\n\n3 bottles of beer on the wall, 3 bottles of beer.\nTake one down and pass it around, 2 bottles of beer on the wall.\n\n2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n\n1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n\nNo more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n```\n"
  },
  {
    "path": "exercises/practice/beer-song/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/BeerSong.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/BeerSongTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/BeerSong.kt\"\n    ]\n  },\n  \"blurb\": \"Produce the lyrics to that beloved classic, that field-trip favorite: 99 Bottles of Beer on the Wall.\",\n  \"source\": \"Learn to Program by Chris Pine\",\n  \"source_url\": \"https://pine.fm/LearnToProgram/?Chapter=06\"\n}\n"
  },
  {
    "path": "exercises/practice/beer-song/.meta/src/reference/kotlin/BeerSong.kt",
    "content": "object BeerSong {\n\n    fun verses(startBottles: Int, takeDown: Int) = (startBottles downTo takeDown).joinToString(\"\\n\") { verse(it) }\n\n    private fun verse(number: Int) = when (number) {\n        0 -> \"No more bottles of beer on the wall, no more bottles of beer.\\nGo to the store and buy some more, 99 bottles of beer on the wall.\\n\"\n        1 -> \"1 bottle of beer on the wall, 1 bottle of beer.\\nTake it down and pass it around, no more bottles of beer on the wall.\\n\"\n        2 -> \"2 bottles of beer on the wall, 2 bottles of beer.\\nTake one down and pass it around, 1 bottle of beer on the wall.\\n\"\n        in 3..99 -> \"$number bottles of beer on the wall, $number bottles of beer.\\nTake one down and pass it around, ${number - 1} bottles of beer on the wall.\\n\"\n        else -> throw IllegalArgumentException(\"Invalid verse number: $number, must be within 0 and 99\")\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/beer-song/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# first generic verse\n\"5a02fd08-d336-4607-8006-246fe6fa9fb0\" = true\n\n# last generic verse\n\"77299ca6-545e-4217-a9cc-606b342e0187\" = true\n\n# verse with 2 bottles\n\"102cbca0-b197-40fd-b548-e99609b06428\" = true\n\n# verse with 1 bottle\n\"b8ef9fce-960e-4d85-a0c9-980a04ec1972\" = true\n\n# verse with 0 bottles\n\"c59d4076-f671-4ee3-baaa-d4966801f90d\" = true\n\n# first two verses\n\"7e17c794-402d-4ca6-8f96-4d8f6ee1ec7e\" = true\n\n# last three verses\n\"949868e7-67e8-43d3-9bb4-69277fe020fb\" = true\n\n# all verses\n\"bc220626-126c-4e72-8df4-fddfc0c3e458\" = true\n"
  },
  {
    "path": "exercises/practice/beer-song/.meta/version",
    "content": "2.1.0\n"
  },
  {
    "path": "exercises/practice/beer-song/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/beer-song/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/beer-song/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/beer-song/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/beer-song/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/beer-song/src/main/kotlin/BeerSong.kt",
    "content": "object BeerSong {\n    fun verses(startBottles: Int, takeDown: Int): String {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/beer-song/src/test/kotlin/BeerSongTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass BeerSongTest {\n\n    @Test\n    fun firstGenericVerse() {\n        val expected = \"99 bottles of beer on the wall, 99 bottles of beer.\\nTake one down and pass it around, 98 bottles of beer on the wall.\\n\"\n        assertEquals(expected, BeerSong.verses(99, 99))\n    }\n\n    @Ignore\n    @Test\n    fun lastGenericVerse() {\n        val expected = \"3 bottles of beer on the wall, 3 bottles of beer.\\nTake one down and pass it around, 2 bottles of beer on the wall.\\n\"\n        assertEquals(expected, BeerSong.verses(3, 3))\n    }\n\n    @Ignore\n    @Test\n    fun verse2() {\n        val expected = \"2 bottles of beer on the wall, 2 bottles of beer.\\nTake one down and pass it around, 1 bottle of beer on the wall.\\n\"\n        assertEquals(expected, BeerSong.verses(2, 2))\n    }\n\n    @Ignore\n    @Test\n    fun verse1() {\n        val expected = \"1 bottle of beer on the wall, 1 bottle of beer.\\nTake it down and pass it around, no more bottles of beer on the wall.\\n\"\n        assertEquals(expected, BeerSong.verses(1, 1))\n    }\n\n    @Ignore\n    @Test\n    fun verse0() {\n        val expected = \"No more bottles of beer on the wall, no more bottles of beer.\\nGo to the store and buy some more, 99 bottles of beer on the wall.\\n\"\n        assertEquals(expected, BeerSong.verses(0, 0))\n    }\n\n    @Ignore\n    @Test\n    fun firstTwoVerses() {\n        val expected = \"99 bottles of beer on the wall, 99 bottles of beer.\\nTake one down and pass it around, 98 bottles of beer on the wall.\\n\\n98 bottles of beer on the wall, 98 bottles of beer.\\nTake one down and pass it around, 97 bottles of beer on the wall.\\n\"\n        assertEquals(expected, BeerSong.verses(99, 98))\n    }\n\n    @Ignore\n    @Test\n    fun lastThreeVerses() {\n        val expected = \"2 bottles of beer on the wall, 2 bottles of beer.\\nTake one down and pass it around, 1 bottle of beer on the wall.\\n\\n1 bottle of beer on the wall, 1 bottle of beer.\\nTake it down and pass it around, no more bottles of beer on the wall.\\n\\nNo more bottles of beer on the wall, no more bottles of beer.\\nGo to the store and buy some more, 99 bottles of beer on the wall.\\n\"\n        assertEquals(expected, BeerSong.verses(2, 0))\n    }\n\n    @Ignore\n    @Test\n    fun allVerses() {\n        val expected =\n                \"\"\"99 bottles of beer on the wall, 99 bottles of beer.\nTake one down and pass it around, 98 bottles of beer on the wall.\n\n98 bottles of beer on the wall, 98 bottles of beer.\nTake one down and pass it around, 97 bottles of beer on the wall.\n\n97 bottles of beer on the wall, 97 bottles of beer.\nTake one down and pass it around, 96 bottles of beer on the wall.\n\n96 bottles of beer on the wall, 96 bottles of beer.\nTake one down and pass it around, 95 bottles of beer on the wall.\n\n95 bottles of beer on the wall, 95 bottles of beer.\nTake one down and pass it around, 94 bottles of beer on the wall.\n\n94 bottles of beer on the wall, 94 bottles of beer.\nTake one down and pass it around, 93 bottles of beer on the wall.\n\n93 bottles of beer on the wall, 93 bottles of beer.\nTake one down and pass it around, 92 bottles of beer on the wall.\n\n92 bottles of beer on the wall, 92 bottles of beer.\nTake one down and pass it around, 91 bottles of beer on the wall.\n\n91 bottles of beer on the wall, 91 bottles of beer.\nTake one down and pass it around, 90 bottles of beer on the wall.\n\n90 bottles of beer on the wall, 90 bottles of beer.\nTake one down and pass it around, 89 bottles of beer on the wall.\n\n89 bottles of beer on the wall, 89 bottles of beer.\nTake one down and pass it around, 88 bottles of beer on the wall.\n\n88 bottles of beer on the wall, 88 bottles of beer.\nTake one down and pass it around, 87 bottles of beer on the wall.\n\n87 bottles of beer on the wall, 87 bottles of beer.\nTake one down and pass it around, 86 bottles of beer on the wall.\n\n86 bottles of beer on the wall, 86 bottles of beer.\nTake one down and pass it around, 85 bottles of beer on the wall.\n\n85 bottles of beer on the wall, 85 bottles of beer.\nTake one down and pass it around, 84 bottles of beer on the wall.\n\n84 bottles of beer on the wall, 84 bottles of beer.\nTake one down and pass it around, 83 bottles of beer on the wall.\n\n83 bottles of beer on the wall, 83 bottles of beer.\nTake one down and pass it around, 82 bottles of beer on the wall.\n\n82 bottles of beer on the wall, 82 bottles of beer.\nTake one down and pass it around, 81 bottles of beer on the wall.\n\n81 bottles of beer on the wall, 81 bottles of beer.\nTake one down and pass it around, 80 bottles of beer on the wall.\n\n80 bottles of beer on the wall, 80 bottles of beer.\nTake one down and pass it around, 79 bottles of beer on the wall.\n\n79 bottles of beer on the wall, 79 bottles of beer.\nTake one down and pass it around, 78 bottles of beer on the wall.\n\n78 bottles of beer on the wall, 78 bottles of beer.\nTake one down and pass it around, 77 bottles of beer on the wall.\n\n77 bottles of beer on the wall, 77 bottles of beer.\nTake one down and pass it around, 76 bottles of beer on the wall.\n\n76 bottles of beer on the wall, 76 bottles of beer.\nTake one down and pass it around, 75 bottles of beer on the wall.\n\n75 bottles of beer on the wall, 75 bottles of beer.\nTake one down and pass it around, 74 bottles of beer on the wall.\n\n74 bottles of beer on the wall, 74 bottles of beer.\nTake one down and pass it around, 73 bottles of beer on the wall.\n\n73 bottles of beer on the wall, 73 bottles of beer.\nTake one down and pass it around, 72 bottles of beer on the wall.\n\n72 bottles of beer on the wall, 72 bottles of beer.\nTake one down and pass it around, 71 bottles of beer on the wall.\n\n71 bottles of beer on the wall, 71 bottles of beer.\nTake one down and pass it around, 70 bottles of beer on the wall.\n\n70 bottles of beer on the wall, 70 bottles of beer.\nTake one down and pass it around, 69 bottles of beer on the wall.\n\n69 bottles of beer on the wall, 69 bottles of beer.\nTake one down and pass it around, 68 bottles of beer on the wall.\n\n68 bottles of beer on the wall, 68 bottles of beer.\nTake one down and pass it around, 67 bottles of beer on the wall.\n\n67 bottles of beer on the wall, 67 bottles of beer.\nTake one down and pass it around, 66 bottles of beer on the wall.\n\n66 bottles of beer on the wall, 66 bottles of beer.\nTake one down and pass it around, 65 bottles of beer on the wall.\n\n65 bottles of beer on the wall, 65 bottles of beer.\nTake one down and pass it around, 64 bottles of beer on the wall.\n\n64 bottles of beer on the wall, 64 bottles of beer.\nTake one down and pass it around, 63 bottles of beer on the wall.\n\n63 bottles of beer on the wall, 63 bottles of beer.\nTake one down and pass it around, 62 bottles of beer on the wall.\n\n62 bottles of beer on the wall, 62 bottles of beer.\nTake one down and pass it around, 61 bottles of beer on the wall.\n\n61 bottles of beer on the wall, 61 bottles of beer.\nTake one down and pass it around, 60 bottles of beer on the wall.\n\n60 bottles of beer on the wall, 60 bottles of beer.\nTake one down and pass it around, 59 bottles of beer on the wall.\n\n59 bottles of beer on the wall, 59 bottles of beer.\nTake one down and pass it around, 58 bottles of beer on the wall.\n\n58 bottles of beer on the wall, 58 bottles of beer.\nTake one down and pass it around, 57 bottles of beer on the wall.\n\n57 bottles of beer on the wall, 57 bottles of beer.\nTake one down and pass it around, 56 bottles of beer on the wall.\n\n56 bottles of beer on the wall, 56 bottles of beer.\nTake one down and pass it around, 55 bottles of beer on the wall.\n\n55 bottles of beer on the wall, 55 bottles of beer.\nTake one down and pass it around, 54 bottles of beer on the wall.\n\n54 bottles of beer on the wall, 54 bottles of beer.\nTake one down and pass it around, 53 bottles of beer on the wall.\n\n53 bottles of beer on the wall, 53 bottles of beer.\nTake one down and pass it around, 52 bottles of beer on the wall.\n\n52 bottles of beer on the wall, 52 bottles of beer.\nTake one down and pass it around, 51 bottles of beer on the wall.\n\n51 bottles of beer on the wall, 51 bottles of beer.\nTake one down and pass it around, 50 bottles of beer on the wall.\n\n50 bottles of beer on the wall, 50 bottles of beer.\nTake one down and pass it around, 49 bottles of beer on the wall.\n\n49 bottles of beer on the wall, 49 bottles of beer.\nTake one down and pass it around, 48 bottles of beer on the wall.\n\n48 bottles of beer on the wall, 48 bottles of beer.\nTake one down and pass it around, 47 bottles of beer on the wall.\n\n47 bottles of beer on the wall, 47 bottles of beer.\nTake one down and pass it around, 46 bottles of beer on the wall.\n\n46 bottles of beer on the wall, 46 bottles of beer.\nTake one down and pass it around, 45 bottles of beer on the wall.\n\n45 bottles of beer on the wall, 45 bottles of beer.\nTake one down and pass it around, 44 bottles of beer on the wall.\n\n44 bottles of beer on the wall, 44 bottles of beer.\nTake one down and pass it around, 43 bottles of beer on the wall.\n\n43 bottles of beer on the wall, 43 bottles of beer.\nTake one down and pass it around, 42 bottles of beer on the wall.\n\n42 bottles of beer on the wall, 42 bottles of beer.\nTake one down and pass it around, 41 bottles of beer on the wall.\n\n41 bottles of beer on the wall, 41 bottles of beer.\nTake one down and pass it around, 40 bottles of beer on the wall.\n\n40 bottles of beer on the wall, 40 bottles of beer.\nTake one down and pass it around, 39 bottles of beer on the wall.\n\n39 bottles of beer on the wall, 39 bottles of beer.\nTake one down and pass it around, 38 bottles of beer on the wall.\n\n38 bottles of beer on the wall, 38 bottles of beer.\nTake one down and pass it around, 37 bottles of beer on the wall.\n\n37 bottles of beer on the wall, 37 bottles of beer.\nTake one down and pass it around, 36 bottles of beer on the wall.\n\n36 bottles of beer on the wall, 36 bottles of beer.\nTake one down and pass it around, 35 bottles of beer on the wall.\n\n35 bottles of beer on the wall, 35 bottles of beer.\nTake one down and pass it around, 34 bottles of beer on the wall.\n\n34 bottles of beer on the wall, 34 bottles of beer.\nTake one down and pass it around, 33 bottles of beer on the wall.\n\n33 bottles of beer on the wall, 33 bottles of beer.\nTake one down and pass it around, 32 bottles of beer on the wall.\n\n32 bottles of beer on the wall, 32 bottles of beer.\nTake one down and pass it around, 31 bottles of beer on the wall.\n\n31 bottles of beer on the wall, 31 bottles of beer.\nTake one down and pass it around, 30 bottles of beer on the wall.\n\n30 bottles of beer on the wall, 30 bottles of beer.\nTake one down and pass it around, 29 bottles of beer on the wall.\n\n29 bottles of beer on the wall, 29 bottles of beer.\nTake one down and pass it around, 28 bottles of beer on the wall.\n\n28 bottles of beer on the wall, 28 bottles of beer.\nTake one down and pass it around, 27 bottles of beer on the wall.\n\n27 bottles of beer on the wall, 27 bottles of beer.\nTake one down and pass it around, 26 bottles of beer on the wall.\n\n26 bottles of beer on the wall, 26 bottles of beer.\nTake one down and pass it around, 25 bottles of beer on the wall.\n\n25 bottles of beer on the wall, 25 bottles of beer.\nTake one down and pass it around, 24 bottles of beer on the wall.\n\n24 bottles of beer on the wall, 24 bottles of beer.\nTake one down and pass it around, 23 bottles of beer on the wall.\n\n23 bottles of beer on the wall, 23 bottles of beer.\nTake one down and pass it around, 22 bottles of beer on the wall.\n\n22 bottles of beer on the wall, 22 bottles of beer.\nTake one down and pass it around, 21 bottles of beer on the wall.\n\n21 bottles of beer on the wall, 21 bottles of beer.\nTake one down and pass it around, 20 bottles of beer on the wall.\n\n20 bottles of beer on the wall, 20 bottles of beer.\nTake one down and pass it around, 19 bottles of beer on the wall.\n\n19 bottles of beer on the wall, 19 bottles of beer.\nTake one down and pass it around, 18 bottles of beer on the wall.\n\n18 bottles of beer on the wall, 18 bottles of beer.\nTake one down and pass it around, 17 bottles of beer on the wall.\n\n17 bottles of beer on the wall, 17 bottles of beer.\nTake one down and pass it around, 16 bottles of beer on the wall.\n\n16 bottles of beer on the wall, 16 bottles of beer.\nTake one down and pass it around, 15 bottles of beer on the wall.\n\n15 bottles of beer on the wall, 15 bottles of beer.\nTake one down and pass it around, 14 bottles of beer on the wall.\n\n14 bottles of beer on the wall, 14 bottles of beer.\nTake one down and pass it around, 13 bottles of beer on the wall.\n\n13 bottles of beer on the wall, 13 bottles of beer.\nTake one down and pass it around, 12 bottles of beer on the wall.\n\n12 bottles of beer on the wall, 12 bottles of beer.\nTake one down and pass it around, 11 bottles of beer on the wall.\n\n11 bottles of beer on the wall, 11 bottles of beer.\nTake one down and pass it around, 10 bottles of beer on the wall.\n\n10 bottles of beer on the wall, 10 bottles of beer.\nTake one down and pass it around, 9 bottles of beer on the wall.\n\n9 bottles of beer on the wall, 9 bottles of beer.\nTake one down and pass it around, 8 bottles of beer on the wall.\n\n8 bottles of beer on the wall, 8 bottles of beer.\nTake one down and pass it around, 7 bottles of beer on the wall.\n\n7 bottles of beer on the wall, 7 bottles of beer.\nTake one down and pass it around, 6 bottles of beer on the wall.\n\n6 bottles of beer on the wall, 6 bottles of beer.\nTake one down and pass it around, 5 bottles of beer on the wall.\n\n5 bottles of beer on the wall, 5 bottles of beer.\nTake one down and pass it around, 4 bottles of beer on the wall.\n\n4 bottles of beer on the wall, 4 bottles of beer.\nTake one down and pass it around, 3 bottles of beer on the wall.\n\n3 bottles of beer on the wall, 3 bottles of beer.\nTake one down and pass it around, 2 bottles of beer on the wall.\n\n2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n\n1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n\nNo more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n\"\"\"\n        assertEquals(expected, BeerSong.verses(99, 0))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/binary/.docs/instructions.md",
    "content": "# Instructions\n\nConvert a binary number, represented as a string (e.g. '101010'), to its decimal equivalent using first principles.\n\nImplement binary to decimal conversion. Given a binary input\nstring, your program should produce a decimal output. The\nprogram should handle invalid inputs.\n\n## Note\n\n- Implement the conversion yourself.\n  Do not use something else to perform the conversion for you.\n\n## About Binary (Base-2)\n\nDecimal is a base-10 system.\n\nA number 23 in base 10 notation can be understood\nas a linear combination of powers of 10:\n\n- The rightmost digit gets multiplied by 10^0 = 1\n- The next number gets multiplied by 10^1 = 10\n- ...\n- The *n*th number gets multiplied by 10^*(n-1)*.\n- All these values are summed.\n\nSo: `23 => 2*10^1 + 3*10^0 => 2*10 + 3*1 = 23 base 10`\n\nBinary is similar, but uses powers of 2 rather than powers of 10.\n\nSo: `101 => 1*2^2 + 0*2^1 + 1*2^0 => 1*4 + 0*2 + 1*1 => 4 + 1 => 5 base 10`.\n"
  },
  {
    "path": "exercises/practice/binary/.meta/config.json",
    "content": "{\n  \"blurb\": \"Convert a binary number, represented as a string (e.g. '101010'), to its decimal equivalent using first principles\",\n  \"authors\": [\"sdavids13\"],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"kytrinyx\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\"src/main/kotlin/Binary.kt\"],\n    \"test\": [\"src/test/kotlin/BinaryTest.kt\"],\n    \"example\": [\".meta/src/reference/kotlin/Binary.kt\"]\n  },\n  \"source\": \"All of Computer Science\",\n  \"source_url\": \"http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-\"\n}\n"
  },
  {
    "path": "exercises/practice/binary/.meta/src/reference/kotlin/Binary.kt",
    "content": "object Binary {\n    fun toDecimal(s: String): Int {\n        return s.fold(0) { accum, char ->\n            when (char) {\n                '0' -> accum * 2\n                '1' -> (accum * 2) + 1\n                else -> return 0\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/binary/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# binary 0 is decimal 0\n\"567fc71e-1013-4915-9285-bca0648c0844\" = true\n\n# binary 1 is decimal 1\n\"c0824fb1-6a0a-4e9a-a262-c6c00af99fa8\" = true\n\n# binary 10 is decimal 2\n\"4d2834fb-3cc3-4159-a8fd-da1098def8ed\" = true\n\n# binary 11 is decimal 3\n\"b7b2b649-4a7c-4808-9eb9-caf00529bac6\" = true\n\n# binary 100 is decimal 4\n\"de761aff-73cd-43c1-9e1f-0417f07b1e4a\" = true\n\n# binary 1001 is decimal 9\n\"7849a8f7-f4a1-4966-963e-503282d6814c\" = true\n\n# binary 11010 is decimal 26\n\"836a101c-aecb-473b-ba78-962408dcda98\" = true\n\n# binary 10001101000 is decimal 1128\n\"1c6822a4-8584-438b-8dd4-40f0f0b66371\" = true\n\n# binary ignores leading zeros\n\"91ffe632-8374-4016-b1d1-d8400d9f940d\" = true\n\n# 2 is not a valid binary digit\n\"44f7d8b1-ddc3-4751-8be3-700a538b421c\" = true\n\n# a number containing a non-binary digit is invalid\n\"c263a24d-6870-420f-b783-628feefd7b6e\" = true\n\n# a number with trailing non-binary characters is invalid\n\"8d81305b-0502-4a07-bfba-051c5526d7f2\" = true\n\n# a number with leading non-binary characters is invalid\n\"a7f79b6b-039a-4d42-99b4-fcee56679f03\" = true\n\n# a number with internal non-binary characters is invalid\n\"9e0ece9d-b8aa-46a0-a22b-3bed2e3f741e\" = true\n\n# a number and a word whitespace separated is invalid\n\"46c8dd65-0c32-4273-bb0d-f2b111bccfbd\" = true\n"
  },
  {
    "path": "exercises/practice/binary/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/binary/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/binary/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/binary/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/binary/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/binary/src/main/kotlin/Binary.kt",
    "content": "object Binary {\n    fun toDecimal(s: String): Int {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/binary/src/test/kotlin/BinaryTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport org.junit.runner.RunWith\nimport org.junit.runners.Parameterized\nimport kotlin.test.assertEquals\n\n@RunWith(Parameterized::class)\nclass BinaryTest(val input: String, val expectedOutput: Int) {\n\n    companion object {\n        @JvmStatic\n        @Parameterized.Parameters(name = \"{index}: binary({0})={1}\")\n        fun data() = listOf(\n                arrayOf(\"1\", 1),\n                arrayOf(\"10\", 2),\n                arrayOf(\"11\", 3),\n                arrayOf(\"100\", 4),\n                arrayOf(\"1001\", 9),\n                arrayOf(\"11010\", 26),\n                arrayOf(\"10001101000\", 1128),\n                arrayOf(\"2\", 0),\n                arrayOf(\"5\", 0),\n                arrayOf(\"9\", 0),\n                arrayOf(\"134678\", 0),\n                arrayOf(\"abc10z\", 0),\n                arrayOf(\"011\", 3),\n                arrayOf(\"g1\", 0)\n        )\n    }\n\n\n    @Test\n    fun binaryStringToInt() {\n        assertEquals(expectedOutput, Binary.toDecimal(input))\n    }\n}\n"
  },
  {
    "path": "exercises/practice/binary-search/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to implement a binary search algorithm.\n\nA binary search algorithm finds an item in a list by repeatedly splitting it in half, only keeping the half which contains the item we're looking for.\nIt allows us to quickly narrow down the possible locations of our item until we find it, or until we've eliminated all possible locations.\n\n~~~~exercism/caution\nBinary search only works when a list has been sorted.\n~~~~\n\nThe algorithm looks like this:\n\n- Find the middle element of a _sorted_ list and compare it with the item we're looking for.\n- If the middle element is our item, then we're done!\n- If the middle element is greater than our item, we can eliminate that element and all the elements **after** it.\n- If the middle element is less than our item, we can eliminate that element and all the elements **before** it.\n- If every element of the list has been eliminated then the item is not in the list.\n- Otherwise, repeat the process on the part of the list that has not been eliminated.\n\nHere's an example:\n\nLet's say we're looking for the number 23 in the following sorted list: `[4, 8, 12, 16, 23, 28, 32]`.\n\n- We start by comparing 23 with the middle element, 16.\n- Since 23 is greater than 16, we can eliminate the left half of the list, leaving us with `[23, 28, 32]`.\n- We then compare 23 with the new middle element, 28.\n- Since 23 is less than 28, we can eliminate the right half of the list: `[23]`.\n- We've found our item.\n"
  },
  {
    "path": "exercises/practice/binary-search/.docs/introduction.md",
    "content": "# Introduction\n\nYou have stumbled upon a group of mathematicians who are also singer-songwriters.\nThey have written a song for each of their favorite numbers, and, as you can imagine, they have a lot of favorite numbers (like [0][zero] or [73][seventy-three] or [6174][kaprekars-constant]).\n\nYou are curious to hear the song for your favorite number, but with so many songs to wade through, finding the right song could take a while.\nFortunately, they have organized their songs in a playlist sorted by the title — which is simply the number that the song is about.\n\nYou realize that you can use a binary search algorithm to quickly find a song given the title.\n\n[zero]: https://en.wikipedia.org/wiki/0\n[seventy-three]: https://en.wikipedia.org/wiki/73_(number)\n[kaprekars-constant]: https://en.wikipedia.org/wiki/6174_(number)\n"
  },
  {
    "path": "exercises/practice/binary-search/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"geoand\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/BinarySearch.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/BinarySearchTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/BinarySearch.kt\"\n    ]\n  },\n  \"blurb\": \"Implement a binary search algorithm.\",\n  \"source\": \"Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Binary_search_algorithm\"\n}\n"
  },
  {
    "path": "exercises/practice/binary-search/.meta/src/reference/kotlin/BinarySearch.kt",
    "content": "object BinarySearch {\n\n    fun <T: Comparable<T>> search(list: List<T>, item: T) : Int {\n        require(list.isSorted()) {\"The provided list must be sorted in ascending order\"}\n\n        if(list.isEmpty()) {\n            throw NoSuchElementException(\"value $item is not in array $list\")\n        }\n\n        return searchRec(list, item, 0)\n    }\n\n    private tailrec fun <T: Comparable<T>> searchRec(list: List<T>, item: T, accumulatedOffset: Int) : Int {\n        if(1 == list.size) {\n            return if(list.first() == item) accumulatedOffset else throw NoSuchElementException(\"value $item is not in array $list\")\n        }\n\n        val midIndex = list.size / 2\n        val midValue = list[midIndex]\n\n        if(item < midValue) {\n            return searchRec(list.subList(0, midIndex), item, accumulatedOffset)\n        }\n\n        return searchRec(list.subList(midIndex, list.size), item, midIndex + accumulatedOffset)\n    }\n\n    /**\n     * The following extension methods are more general, in a project they would probably not be private\n     */\n\n\n    /**\n     * Uses a sequence of Pair objects in order to avoid calculating all the pairs beforehand in cases\n     * where the list is not sorted\n     */\n    private fun <T: Comparable<T>> List<T>.isSorted(): Boolean {\n        if(this.isEmpty()) {\n            return true\n        }\n\n        return this.pairsSequence().all { it.first <= it.second }\n    }\n\n    /**\n     * Returns a sequence of Pair objects containing all each object of the list plus it's following object\n     */\n    private fun <T> List<T>.pairsSequence() : Sequence<Pair<T, T>> {\n        if(this.size < 2) {\n            return emptySequence()\n        }\n\n        val list = this\n        return object : Sequence<Pair<T, T>> {\n            override fun iterator(): Iterator<Pair<T, T>> {\n                return object: AbstractIterator<Pair<T, T>>() {\n\n                    var index = 0\n\n                    override fun computeNext() {\n                        if(index >= (list.size-1)) {\n                            done()\n                        }\n                        else {\n                            setNext(Pair(list[index], list[index+1]))\n                            index += 1\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n}\n\n\n"
  },
  {
    "path": "exercises/practice/binary-search/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# finds a value in an array with one element\n\"b55c24a9-a98d-4379-a08c-2adcf8ebeee8\" = true\n\n# finds a value in the middle of an array\n\"73469346-b0a0-4011-89bf-989e443d503d\" = true\n\n# finds a value at the beginning of an array\n\"327bc482-ab85-424e-a724-fb4658e66ddb\" = true\n\n# finds a value at the end of an array\n\"f9f94b16-fe5e-472c-85ea-c513804c7d59\" = true\n\n# finds a value in an array of odd length\n\"f0068905-26e3-4342-856d-ad153cadb338\" = true\n\n# finds a value in an array of even length\n\"fc316b12-c8b3-4f5e-9e89-532b3389de8c\" = true\n\n# identifies that a value is not included in the array\n\"da7db20a-354f-49f7-a6a1-650a54998aa6\" = true\n\n# a value smaller than the array's smallest value is not found\n\"95d869ff-3daf-4c79-b622-6e805c675f97\" = true\n\n# a value larger than the array's largest value is not found\n\"8b24ef45-6e51-4a94-9eac-c2bf38fdb0ba\" = true\n\n# nothing is found in an empty array\n\"f439a0fa-cf42-4262-8ad1-64bf41ce566a\" = true\n\n# nothing is found when the left and right bounds cross\n\"2c353967-b56d-40b8-acff-ce43115eed64\" = true\n"
  },
  {
    "path": "exercises/practice/binary-search/.meta/version",
    "content": "1.3.0\n"
  },
  {
    "path": "exercises/practice/binary-search/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/binary-search/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/binary-search/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/binary-search/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/binary-search/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/binary-search/src/main/kotlin/BinarySearch.kt",
    "content": "object BinarySearch {\n    fun search(list: List<Int>, item: Int): Int {\n        TODO(\"Implement the function to complete the task. Change the signature if necessary.\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/binary-search/src/test/kotlin/BinarySearchTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass BinarySearchTest {\n\n    @Test\n    fun `finds value in array with one element`() =\n            assertEquals(0, BinarySearch.search(listOf(6), 6))\n\n    @Ignore\n    @Test\n    fun `finds value in the middle of array`() =\n            assertEquals(3, BinarySearch.search(listOf(1, 3, 4, 6, 8, 9, 11), 6))\n\n\n    @Ignore\n    @Test\n    fun `finds value at the beginning of array`() =\n            assertEquals(0, BinarySearch.search(listOf(1, 3, 4, 6, 8, 9, 11), 1))\n\n    @Ignore\n    @Test\n    fun `finds value at the end of array`() =\n            assertEquals(6, BinarySearch.search(listOf(1, 3, 4, 6, 8, 9, 11), 11))\n\n    @Ignore\n    @Test\n    fun `finds value in array of odd length`() =\n            assertEquals(9, BinarySearch.search(listOf(1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 634), 144))\n\n    @Ignore\n    @Test\n    fun `finds value in array of even length`() =\n            assertEquals(5, BinarySearch.search(listOf(1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377), 21))\n\n    @Ignore\n    @Test(expected = NoSuchElementException::class)\n    fun `identifies that value is not included in array`() {\n        BinarySearch.search(listOf(1, 3, 4, 6, 8, 9, 11), 7)\n    }\n\n    @Ignore\n    @Test(expected = NoSuchElementException::class)\n    fun `value smaller than array's smallest value is not found`() {\n        BinarySearch.search(listOf(1, 3, 4, 6, 8, 9, 11), 0)\n    }\n\n    @Ignore\n    @Test(expected = NoSuchElementException::class)\n    fun `value larger than array's largest value is not found`() {\n        BinarySearch.search(listOf(1, 3, 4, 6, 8, 9, 11), 13)\n    }\n\n    @Ignore\n    @Test(expected = NoSuchElementException::class)\n    fun `nothing is found in empty array`() {\n        BinarySearch.search(emptyList(), 1)\n    }\n\n    @Ignore\n    @Test(expected = NoSuchElementException::class)\n    fun `nothing is found when left and right bounds cross`() {\n        BinarySearch.search(listOf(1, 2), 0)\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/binary-search-tree/.docs/instructions.md",
    "content": "# Instructions\n\nInsert and search for numbers in a binary tree.\n\nWhen we need to represent sorted data, an array does not make a good data structure.\n\nSay we have the array `[1, 3, 4, 5]`, and we add 2 to it so it becomes `[1, 3, 4, 5, 2]`.\nNow we must sort the entire array again!\nWe can improve on this by realizing that we only need to make space for the new item `[1, nil, 3, 4, 5]`, and then adding the item in the space we added.\nBut this still requires us to shift many elements down by one.\n\nBinary Search Trees, however, can operate on sorted data much more efficiently.\n\nA binary search tree consists of a series of connected nodes.\nEach node contains a piece of data (e.g. the number 3), a variable named `left`, and a variable named `right`.\nThe `left` and `right` variables point at `nil`, or other nodes.\nSince these other nodes in turn have other nodes beneath them, we say that the left and right variables are pointing at subtrees.\nAll data in the left subtree is less than or equal to the current node's data, and all data in the right subtree is greater than the current node's data.\n\nFor example, if we had a node containing the data 4, and we added the data 2, our tree would look like this:\n\n      4\n     /\n    2\n\nIf we then added 6, it would look like this:\n\n      4\n     / \\\n    2   6\n\nIf we then added 3, it would look like this\n\n       4\n     /   \\\n    2     6\n     \\\n      3\n\nAnd if we then added 1, 5, and 7, it would look like this\n\n          4\n        /   \\\n       /     \\\n      2       6\n     / \\     / \\\n    1   3   5   7\n"
  },
  {
    "path": "exercises/practice/binary-search-tree/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"glennj\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/BinarySearchTree.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/BinarySearchTreeTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/BinarySearchTree.kt\"\n    ]\n  },\n  \"blurb\": \"Insert and search for numbers in a binary tree.\",\n  \"source\": \"Josh Cheek\"\n}\n"
  },
  {
    "path": "exercises/practice/binary-search-tree/.meta/src/reference/kotlin/BinarySearchTree.kt",
    "content": "class BinarySearchTree<T : Comparable<T>> {\n\n    data class Node<T>(val data: T, var left: Node<T>? = null, var right: Node<T>? = null)\n\n    var root: Node<T>? = null\n\n    fun insert(value: T) {\n        if (root == null) {\n            root = Node(value)\n        } else {\n            insert(value, root!!)\n        }\n    }\n\n    private fun insert(value: T, parent: Node<T>) {\n        if (value > parent.data) {\n            if (parent.right == null) {\n                parent.right = Node(value)\n            } else {\n                insert(value, parent.right!!)\n            }\n        } else {\n            // Equal elements are inserted on the left side, too!\n            if (parent.left == null) {\n                parent.left = Node(value)\n            } else {\n                insert(value, parent.left!!)\n            }\n        }\n    }\n\n    fun asSortedList(): List<T> {\n        return asSortedList(root).map { it.data }\n    }\n\n    private fun asSortedList(start: Node<T>?): List<Node<T>> =\n            if (start == null) {\n                emptyList()\n            } else {\n                asSortedList(start.left) + listOf(start) + asSortedList(start.right)\n            }\n\n    fun asLevelOrderList(): List<T> =\n            if (root == null) {\n                emptyList()\n            } else {\n                asLevelOrderList(listOf(), listOf(root!!)).first.map { it.data }\n            }\n\n\n    private fun asLevelOrderList(done: List<Node<T>>, todo: List<Node<T>>): Pair<List<Node<T>>, List<Node<T>>> {\n        if (todo.isEmpty()) {\n            return Pair(done, emptyList())\n        }\n        return asLevelOrderList(\n                done + todo,\n                todo.flatMap { listOfNotNull(it.left, it.right) })\n    }\n}\n"
  },
  {
    "path": "exercises/practice/binary-search-tree/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# data is retained\n\"e9c93a78-c536-4750-a336-94583d23fafa\" = true\n\n# smaller number at left node\n\"7a95c9e8-69f6-476a-b0c4-4170cb3f7c91\" = true\n\n# same number at left node\n\"22b89499-9805-4703-a159-1a6e434c1585\" = true\n\n# greater number at right node\n\"2e85fdde-77b1-41ed-b6ac-26ce6b663e34\" = true\n\n# can create complex tree\n\"dd898658-40ab-41d0-965e-7f145bf66e0b\" = true\n\n# can sort single number\n\"9e0c06ef-aeca-4202-b8e4-97f1ed057d56\" = true\n\n# can sort if second number is smaller than first\n\"425e6d07-fceb-4681-a4f4-e46920e380bb\" = true\n\n# can sort if second number is same as first\n\"bd7532cc-6988-4259-bac8-1d50140079ab\" = true\n\n# can sort if second number is greater than first\n\"b6d1b3a5-9d79-44fd-9013-c83ca92ddd36\" = true\n\n# can sort complex tree\n\"d00ec9bd-1288-4171-b968-d44d0808c1c8\" = true\n"
  },
  {
    "path": "exercises/practice/binary-search-tree/.meta/version",
    "content": "1.0.0\n"
  },
  {
    "path": "exercises/practice/binary-search-tree/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/binary-search-tree/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/binary-search-tree/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/binary-search-tree/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/binary-search-tree/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/binary-search-tree/src/main/kotlin/BinarySearchTree.kt",
    "content": "class BinarySearchTree<T : Comparable<T>> {\n\n    data class Node<T>(val data: T /* maybe more... */)\n\n    var root: Node<T>? = null\n\n    fun insert(value: T) {\n        TODO(\"Delete this statement and write your own implementation.\")\n    }\n\n    fun asSortedList(): List<T> {\n        TODO(\"Delete this statement and write your own implementation.\")\n    }\n\n    fun asLevelOrderList(): List<T> {\n        TODO(\"Delete this statement and write your own implementation.\")\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/binary-search-tree/src/test/kotlin/BinarySearchTreeTest.kt",
    "content": "import kotlin.test.Ignore\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\nimport kotlin.test.assertNotNull\n\nclass BinarySearchTreeTest {\n\n    @Test\n    fun `data is retained`() {\n        val tree = BinarySearchTree<Int>()\n        val expected = 4\n        tree.insert(expected)\n        val root = tree.root\n        assertNotNull(root)\n        val actual = root.data\n        assertEquals(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun `inserts less`() {\n        val tree = BinarySearchTree<Char>()\n        val expectedRoot = '4'\n        val expectedLeft = '2'\n        tree.insert(expectedRoot)\n        tree.insert(expectedLeft)\n        val root = tree.root\n        assertNotNull(root)\n        val left = root.left\n        assertNotNull(left)\n        val actualRoot = root.data\n        val actualLeft = left.data\n        assertEquals(expectedLeft, actualLeft)\n        assertEquals(expectedRoot, actualRoot)\n    }\n\n    @Ignore\n    @Test\n    fun `inserts same`() {\n        val tree = BinarySearchTree<String>()\n        val expectedRoot = \"4\"\n        val expectedLeft = \"4\"\n        tree.insert(expectedRoot)\n        tree.insert(expectedLeft)\n        val root = tree.root\n        assertNotNull(root)\n        val left = root.left\n        assertNotNull(left)\n        val actualRoot = root.data\n        val actualLeft = left.data\n        assertEquals(expectedLeft, actualLeft)\n        assertEquals(expectedRoot, actualRoot)\n    }\n\n    @Ignore\n    @Test\n    fun `inserts right`() {\n        val tree = BinarySearchTree<Int>()\n        val expectedRoot = 4\n        val expectedRight = 5\n        tree.insert(expectedRoot)\n        tree.insert(expectedRight)\n        val root = tree.root\n        assertNotNull(root)\n        val right = root.right\n        assertNotNull(right)\n        val actualRoot = root.data\n        val actualRight = right.data\n        assertEquals(expectedRight, actualRight)\n        assertEquals(expectedRoot, actualRoot)\n    }\n\n    @Ignore\n    @Test\n    fun `creates complex tree`() {\n        val tree = BinarySearchTree<Char>()\n        val expected = listOf('4', '2', '6', '1', '3', '5', '7')\n        val treeData = listOf('4', '2', '6', '1', '3', '5', '7')\n        treeData.forEach(tree::insert)\n        val actual = tree.asLevelOrderList()\n        assertEquals(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun `sorts single element`() {\n        val tree = BinarySearchTree<String>()\n        val expected = listOf(\"2\")\n        tree.insert(\"2\")\n        val actual = tree.asSortedList()\n        assertEquals(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun `sorts collection of two if second inserted is smaller than first`() {\n        val tree = BinarySearchTree<Int>()\n        val expected: List<Int> = listOf(1, 2)\n        tree.insert(2)\n        tree.insert(1)\n        val actual = tree.asSortedList()\n        assertEquals(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun `sorts collection of two if second number is same as first`() {\n        val tree = BinarySearchTree<Char>()\n        val expected = listOf('2', '2')\n        tree.insert('2')\n        tree.insert('2')\n        val actual = tree.asSortedList()\n        assertEquals(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun `sorts collection of two if second inserted is bigger than first`() {\n        val tree = BinarySearchTree<Char>()\n        val expected = listOf('2', '3')\n        tree.insert('2')\n        tree.insert('3')\n        val actual = tree.asSortedList()\n        assertEquals(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun `iterates over complex tree`() {\n        val tree = BinarySearchTree<String>()\n        val expected = listOf(\"1\", \"2\", \"3\", \"5\", \"6\", \"7\")\n        val treeData = listOf(\"2\", \"1\", \"3\", \"6\", \"7\", \"5\")\n        treeData.forEach(tree::insert)\n        val actual = tree.asSortedList()\n        assertEquals(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun `big tree level order`() {\n        val tree = BinarySearchTree<Int>()\n        val expected = listOf(8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15)\n        val treeData = listOf(8, 4, 2, 6, 1, 3, 5, 7, 12, 14, 10, 9, 11, 13, 15)\n        treeData.forEach(tree::insert)\n        val actual = tree.asLevelOrderList()\n        assertEquals(expected, actual)\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bob/.approaches/answer-list/content.md",
    "content": "# Answer `List`\n\n```kotlin\nobject Bob {\n    private val answers =\n            listOf(\"Whatever.\", \"Sure.\", \"Whoa, chill out!\", \"Calm down, I know what I'm doing!\")\n\n    fun hey(input: String): String {\n        val msg = input.trim()\n        if (msg.isEmpty()) return \"Fine. Be that way!\"\n        val isQuestion = if (msg.endsWith('?')) 1 else 0\n        val isYelling = if (('A'..'Z').any { msg.contains(it) } && msg == msg.uppercase()) 2 else 0\n        return answers[isQuestion + isYelling]\n    }\n}\n```\n\nIn this approach you define a `List` that contains Bob’s answers, and each condition is given a score.\nThe correct answer is selected from the `List` by using the score as the `List` index.\n\nAn [object declaration][object] is used to define `Bob` as essentially a [singleton][singleton] object instantiation of the class.\nThis is sufficient, since there is no object state that needs to change with each call of the `hey` method.\n\nThe [`listOf`][listof] method is used to create a list of Bob's answers.\n\nThe `String` [`trim()`][trim] method is applied to the input to eliminate any whitespace at either end of the input.\nIf the string has no characters left, it returns the response for saying nothing.\n\n~~~~exercism/caution\nNote that a `null` `string` would be different from a `String` of all whitespace.\nA `null` `String` would throw a `NullPointerException` if `trim()` were applied to it.\n~~~~\n\nA question is determined by use of the [`endsWith()`][endswith] method to see if the input ends with a question mark.\n\nA [range][range] of `A..Z` is defined to look for uppercase English alphabetic characters.\n\nThe first half of the `isYelling` implementation\n\n```java\nif (('A'..'Z').any { msg.contains(it) }\n```\n\nis constructed from the range and the [`any`][any] method\nto ensure there is at least one uppercase letter character in the `String`.\nThe [lambda][lambda] of `any` uses the [`it`][it] keyword to refer to the single `Char` parameter for the lambda,\nand passes it to the [`contains`][contains] method to check if the character is in the input `String`.\nThe check that there is any alphabetic character is needed, because the second half of the condition tests that the uppercased input is the same as the input.\nIf the input were only `\"123\"` it would equal itself uppercased, but without letters it would not be a yell.\n\nThe conditions of being a question and being a yell are assigned scores through the use of the [ternary expression][ternary-expression].\nFor example, giving a question a score of `1` would use an index of `1` to get the element from the answers `List`, which is `\"Sure.\"`.\n\n| isYelling | isQuestion | Index     | Answer                                |\n| --------- | ---------- | --------- | ------------------------------------- |\n| `false`   | `false`    | 0 + 0 = 0 | `\"Whatever.\"`                         |\n| `false`   | `true`     | 0 + 1 = 1 | `\"Sure.\"`                             |\n| `true`    | `false`    | 2 + 0 = 2 | `\"Whoa, chill out!\"`                  |\n| `true`    | `true`     | 2 + 1 = 3 | `\"Calm down, I know what I'm doing!\"` |\n\n[object]: https://kotlinlang.org/docs/object-declarations.html#object-declarations-overview\n[singleton]: https://en.wikipedia.org/wiki/Singleton_pattern\n[listof]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/list-of.html\n[trim]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/trim.html\n[endswith]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/ends-with.html\n[range]: https://kotlinlang.org/docs/ranges.html#range\n[any]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/any.html\n[contains]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/contains.html\n[ternary-expression]: https://kotlinlang.org/docs/control-flow.html#if-expression\n[lambda]: https://kotlinlang.org/docs/lambdas.html#lambda-expressions-and-anonymous-functions\n[it]: https://kotlinlang.org/docs/lambdas.html#it-implicit-name-of-a-single-parameter\n"
  },
  {
    "path": "exercises/practice/bob/.approaches/answer-list/snippet.txt",
    "content": "fun hey(input: String): String {\n    val msg = input.trim()\n    if (msg.isEmpty()) return \"Fine. Be that way!\"\n    val isQuestion = if (msg.endsWith('?')) 1 else 0\n    val isYelling = if (('A'..'Z').any { msg.contains(it) } && msg == msg.uppercase()) 2 else 0\n    return answers[isQuestion + isYelling]\n}\n"
  },
  {
    "path": "exercises/practice/bob/.approaches/config.json",
    "content": "{\n  \"introduction\": {\n    \"authors\": [\n      \"bobahop\"\n    ]\n  },\n  \"approaches\": [\n    {\n      \"uuid\": \"51d03dc6-c93e-4d49-88b5-89165f00c1d8\",\n      \"slug\": \"if-expressions\",\n      \"title\": \"if expressions\",\n      \"blurb\": \"Use if expressions to return the answer.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    },\n    {\n      \"uuid\": \"1cd79ba8-6786-4ae4-a248-0f89a1daa8a8\",\n      \"slug\": \"answer-list\",\n      \"title\": \"Answer List\",\n      \"blurb\": \"Index into a List to return the answer.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    },\n    {\n      \"uuid\": \"7aebc1df-c23a-42c9-90c4-f022e40d67e9\",\n      \"slug\": \"when-expression\",\n      \"title\": \"when expression\",\n      \"blurb\": \"Use a when expression to return the answer.\",\n      \"authors\": [\n        \"micha-b\"\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "exercises/practice/bob/.approaches/if-expressions/content.md",
    "content": "# `if` expressions\n\n```kotlin\nobject Bob {\n\n    fun hey(input: String): String {\n        val msg = input.trim()\n        if (msg.isEmpty()) return \"Fine. Be that way!\"\n        val isQuestion = msg.endsWith('?')\n        val isYelling = ('A'..'Z').any { msg.contains(it) } && msg == msg.uppercase()\n        if (isYelling)\n                return if (isQuestion) \"Calm down, I know what I'm doing!\" else \"Whoa, chill out!\"\n        else return if (isQuestion) \"Sure.\" else \"Whatever.\"\n    }\n}\n```\n\nIn this approach you have a series of `if` expressions to evaluate the conditions.\nAs soon as the right condition is found, the correct response is returned.\n\nAn [object declaration][object] is used to define `Bob` as essentially a [singleton][singleton] object instantiation of the class.\nThis is sufficient, since there is no object state that needs to change with each call of the `hey` method.\n\nThe `String` [`trim()`][trim] method is applied to the input to eliminate any whitespace at either end of the input.\nIf the string has no characters left, it returns the response for saying nothing.\n\n~~~~exercism/caution\nNote that a `null` `string` would be different from a `String` of all whitespace.\nA `null` `String` would throw a `NullPointerException` if `trim()` were applied to it.\n~~~~\n\nA question is determined by use of the [`endsWith()`][endswith] method to see if the input ends with a question mark.\n\nA [range][range] of `A..Z` is defined to look for uppercase English alphabetic characters.\n\nThe first half of the `isYelling` implementation\n\n```java\nif (('A'..'Z').any { msg.contains(it) }\n```\n\nis constructed from the range and the [`any`][any] method\nto ensure there is at least one uppercase letter character in the `String`.\nThe [lambda][lambda] of `any` uses the [`it`][it] keyword to refer to the single `Char` parameter for the lambda,\nand passes it to the [`contains`][contains] method to check if the character is in the input `String`.\nThe check that there is any alphabetic character is needed, because the second half of the condition tests that the uppercased input is the same as the input.\nIf the input were only `\"123\"` it would equal itself uppercased, but without letters it would not be a yell.\n\nIf `isYelling` is `true`, then a [ternary expresson][ternary-expression] is used to return either the response for a yelled question or just a yell.\n\nIf `isYelling` is `false`, then a ternary expression is used to return either the response for a question or a plain statement.\n\n[object]: https://kotlinlang.org/docs/object-declarations.html#object-declarations-overview\n[singleton]: https://en.wikipedia.org/wiki/Singleton_pattern\n[trim]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/trim.html\n[endswith]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/ends-with.html\n[range]: https://kotlinlang.org/docs/ranges.html#range\n[any]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/any.html\n[contains]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/contains.html\n[ternary-expression]: https://kotlinlang.org/docs/control-flow.html#if-expression\n[lambda]: https://kotlinlang.org/docs/lambdas.html#lambda-expressions-and-anonymous-functions\n[it]: https://kotlinlang.org/docs/lambdas.html#it-implicit-name-of-a-single-parameter\n"
  },
  {
    "path": "exercises/practice/bob/.approaches/if-expressions/snippet.txt",
    "content": "fun hey(input: String): String {\n    val msg = input.trim()\n    if (msg.isEmpty()) return \"Fine. Be that way!\"\n    val isQuestion = msg.endsWith('?')\n    val isYelling = ('A'..'Z').any { msg.contains(it) } && msg == msg.uppercase()\n    if (isYelling)\n            return if (isQuestion) \"Calm down, I know what I'm doing!\" else \"Whoa, chill out!\"\n    else return if (isQuestion) \"Sure.\" else \"Whatever.\"\n"
  },
  {
    "path": "exercises/practice/bob/.approaches/introduction.md",
    "content": "# Introduction\n\nThere are various idiomatic approaches to solve Bob.\nA basic approach can use a series of `if` expressions to test the conditions.\nA `List` can contain answers from which the right response is selected by an index calculated from scores given to the conditions.\n\n## General guidance\n\nRegardless of the approach used, some things you could look out for include\n\n- If the input is trimmed, [`trim()`][trim] only once.\n\n- Use the [`endsWith()`][endswith] method instead of checking the last character by index for `?`.\n\n- Don't copy/paste the logic for determining a shout and for determining a question into determining a shouted question.\n  Combine the two determinations instead of copying them.\n  Not duplicating the code will keep the code [DRY][dry].\n\n- Perhaps consider making `questioning` and `shouting` values set once instead of functions that are possibly called more than once.\n\n## Approach: `if` expressions\n\n```kotlin\nobject Bob {\n\n    fun hey(input: String): String {\n        val msg = input.trim()\n        if (msg.isEmpty()) return \"Fine. Be that way!\"\n        val isQuestion = msg.endsWith('?')\n        val isYelling = ('A'..'Z').any { msg.contains(it) } && msg == msg.uppercase()\n        if (isYelling)\n                return if (isQuestion) \"Calm down, I know what I'm doing!\" else \"Whoa, chill out!\"\n        else return if (isQuestion) \"Sure.\" else \"Whatever.\"\n    }\n}\n```\n\nFor more information, check the [`if` expressions approach][approach-if].\n\n## Approach: Answer `List`\n\n```kotlin\nobject Bob {\n    private val answers =\n            listOf(\"Whatever.\", \"Sure.\", \"Whoa, chill out!\", \"Calm down, I know what I'm doing!\")\n\n    fun hey(input: String): String {\n        val msg = input.trim()\n        if (msg.isEmpty()) return \"Fine. Be that way!\"\n        val isQuestion = if (msg.endsWith('?')) 1 else 0\n        val isYelling = if (('A'..'Z').any { msg.contains(it) } && msg == msg.uppercase()) 2 else 0\n        return answers[isQuestion + isYelling]\n    }\n}\n```\n\nFor more information, check the [Answer `List` approach][approach-answer-list].\n\n## Approach: `when` expression\n\n```kotlin\nobject Bob {\n    fun hey(statement: String): String =\n        when {\n            statement.isQuestion() && statement.isYelling() -> \"Calm down, I know what I'm doing!\"\n            statement.isQuestion() -> \"Sure.\"\n            statement.isYelling() -> \"Whoa, chill out!\"\n            statement.isSilence() -> \"Fine. Be that way!\"\n            else -> \"Whatever.\"\n        }\n}\n```\n\nFor more information, check the [`when` expression approach][approach-when]\n\n## Which approach to use?\n\nThe choice between `if` expressions and answers `List` can be made by perceived readability.\n\n[trim]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/trim.html\n[endswith]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/ends-with.html\n[dry]: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself\n[approach-if]: https://exercism.org/tracks/kotlin/exercises/bob/approaches/if-expressions\n[approach-answer-list]: https://exercism.org/tracks/kotlin/exercises/bob/approaches/answer-list\n[approach-when]: https://exercism.org/tracks/kotlin/exercises/bob/approaches/when-expression\n"
  },
  {
    "path": "exercises/practice/bob/.approaches/when-expression/content.md",
    "content": "# `when` expressions\n\n```kotlin\nobject Bob {\n    fun hey(statement: String): String =\n        when {\n            statement.isQuestion() && statement.isYelling() -> \"Calm down, I know what I'm doing!\"\n            statement.isQuestion() -> \"Sure.\"\n            statement.isYelling() -> \"Whoa, chill out!\"\n            statement.isSilence() -> \"Fine. Be that way!\"\n            else -> \"Whatever.\"\n        }\n\n    private fun String.isSilence(): Boolean = this.isBlank()\n    private fun String.isQuestion(): Boolean = this.trim().endsWith('?')\n    private fun String.isYelling(): Boolean = any(Char::isLetter) && toUpperCase() == this\n}\n```\n\nIn this approach you have a `when` expression containing different so-called branches that can be matched using the corresponding patterns. \nAs soon as one of these patterns on the left side of the arrow (`->`) is matched ...\n\n1. the value on the right side\n2. the block on the right side is executed and the value retuned from the block \n\n... is returned from the `when` expression.\n\nOnly one branch is matched in one execution of the `when` expression. The branches are matched from top to bottom and the first branch in which the condition evaluates to `true` is selected. \nIf none of the given conditions matches the `else` branch is selected and returned.\n\n~~~~exercism/caution\nDepending on what patterns are on the left side of your branches the order of branches is important to the correct execution of the `when` expression since the first matching branch is selected.\n~~~~\n\nAn [object declaration][object] is used to define `Bob` as essentially a [singleton][singleton] object instantiation of the class.\nThis is sufficient, since there is no object state that needs to change with each call of the `hey` method.\n\nInside this object there are some `private` [extension methods as members][extension-members] of the `object`. This adds these methods to the `String` data type for `private` usage of these methods in this `object`. This allows calling the methods directly on the `String` instead of passing the `String` to the method.\n(More about extension methods in general [here][extension-general])\n\nThese extension methods check for:\n\n1. `isSilence()`: a blank string\n2. `isQuestion()`: a string with the last non-whitespace-character being a question mark\n3. `isYelling()`: a string with all letters in uppercase\n\nWhen combining these methods as in the `when` expression above you can map all the cases required by the exercise.\n\n\n[when]: https://kotlinlang.org/docs/control-flow.html#when-expression\n[object]: https://kotlinlang.org/docs/object-declarations.html#object-declarations-overview\n[singleton]: https://en.wikipedia.org/wiki/Singleton_pattern\n[extension-members]: https://kotlinlang.org/docs/extensions.html#declaring-extensions-as-members\n[extension-general]: https://kotlinlang.org/docs/extensions.html"
  },
  {
    "path": "exercises/practice/bob/.approaches/when-expression/snippet.txt",
    "content": "fun hey(statement: String): String =\n    when {\n        statement.isQuestion() && statement.isYelling() -> \"Calm down, I know what I'm doing!\"\n        statement.isQuestion() -> \"Sure.\"\n        statement.isYelling() -> \"Whoa, chill out!\"\n        statement.isSilence() -> \"Fine. Be that way!\"\n        else -> \"Whatever.\"\n    }"
  },
  {
    "path": "exercises/practice/bob/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to determine what Bob will reply to someone when they say something to him or ask him a question.\n\nBob only ever answers one of five things:\n\n- **\"Sure.\"**\n  This is his response if you ask him a question, such as \"How are you?\"\n  The convention used for questions is that it ends with a question mark.\n- **\"Whoa, chill out!\"**\n  This is his answer if you YELL AT HIM.\n  The convention used for yelling is ALL CAPITAL LETTERS.\n- **\"Calm down, I know what I'm doing!\"**\n  This is what he says if you yell a question at him.\n- **\"Fine. Be that way!\"**\n  This is how he responds to silence.\n  The convention used for silence is nothing, or various combinations of whitespace characters.\n- **\"Whatever.\"**\n  This is what he answers to anything else.\n"
  },
  {
    "path": "exercises/practice/bob/.docs/introduction.md",
    "content": "# Introduction\n\nBob is a [lackadaisical][] teenager.\nHe likes to think that he's very cool.\nAnd he definitely doesn't get excited about things.\nThat wouldn't be cool.\n\nWhen people talk to him, his responses are pretty limited.\n\n[lackadaisical]: https://www.collinsdictionary.com/dictionary/english/lackadaisical\n"
  },
  {
    "path": "exercises/practice/bob/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Bob.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/BobTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Bob.kt\"\n    ]\n  },\n  \"blurb\": \"Bob is a lackadaisical teenager. In conversation, his responses are very limited.\",\n  \"source\": \"Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial.\",\n  \"source_url\": \"https://pine.fm/LearnToProgram/?Chapter=06\"\n}\n"
  },
  {
    "path": "exercises/practice/bob/.meta/src/reference/kotlin/Bob.kt",
    "content": "object Bob {\n    fun hey(input: String): String {\n        val trimmedInput = input.trim()\n\n        return when {\n            isSilence(trimmedInput)         -> \"Fine. Be that way!\"\n            isShoutedQuestion(trimmedInput) -> \"Calm down, I know what I'm doing!\"\n            isShout(trimmedInput)           -> \"Whoa, chill out!\"\n            isQuestion(trimmedInput)        -> \"Sure.\"\n            else                            -> \"Whatever.\"\n        }\n    }\n\n    private fun isSilence(input: String) = input.isBlank()\n\n    private fun isQuestion(input: String) = input.endsWith(\"?\")\n\n    private fun isShout(input: String): Boolean {\n        val isOnlyUppercase = input == input.uppercase()\n        val hasLetter = input.contains(Regex(\"[A-Z]\"))\n\n        return hasLetter && isOnlyUppercase\n    }\n\n    private fun isShoutedQuestion(input: String) = isShout(input) && isQuestion(input)\n}\n"
  },
  {
    "path": "exercises/practice/bob/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# stating something\n\"e162fead-606f-437a-a166-d051915cea8e\" = true\n\n# shouting\n\"73a966dc-8017-47d6-bb32-cf07d1a5fcd9\" = true\n\n# shouting gibberish\n\"d6c98afd-df35-4806-b55e-2c457c3ab748\" = true\n\n# asking a question\n\"8a2e771d-d6f1-4e3f-b6c6-b41495556e37\" = true\n\n# asking a numeric question\n\"81080c62-4e4d-4066-b30a-48d8d76920d9\" = true\n\n# asking gibberish\n\"2a02716d-685b-4e2e-a804-2adaf281c01e\" = true\n\n# talking forcefully\n\"c02f9179-ab16-4aa7-a8dc-940145c385f7\" = true\n\n# using acronyms in regular speech\n\"153c0e25-9bb5-4ec5-966e-598463658bcd\" = true\n\n# forceful question\n\"a5193c61-4a92-4f68-93e2-f554eb385ec6\" = true\n\n# shouting numbers\n\"a20e0c54-2224-4dde-8b10-bd2cdd4f61bc\" = true\n\n# no letters\n\"f7bc4b92-bdff-421e-a238-ae97f230ccac\" = true\n\n# question with no letters\n\"bb0011c5-cd52-4a5b-8bfb-a87b6283b0e2\" = true\n\n# shouting with special characters\n\"496143c8-1c31-4c01-8a08-88427af85c66\" = true\n\n# shouting with no exclamation mark\n\"e6793c1c-43bd-4b8d-bc11-499aea73925f\" = true\n\n# statement containing question mark\n\"aa8097cc-c548-4951-8856-14a404dd236a\" = true\n\n# non-letters with question\n\"9bfc677d-ea3a-45f2-be44-35bc8fa3753e\" = true\n\n# prattling on\n\"8608c508-f7de-4b17-985b-811878b3cf45\" = true\n\n# silence\n\"bc39f7c6-f543-41be-9a43-fd1c2f753fc0\" = true\n\n# prolonged silence\n\"d6c47565-372b-4b09-b1dd-c40552b8378b\" = true\n\n# alternate silence\n\"4428f28d-4100-4d85-a902-e5a78cb0ecd3\" = true\n\n# multiple line question\n\"66953780-165b-4e7e-8ce3-4bcb80b6385a\" = true\n\n# starting with whitespace\n\"5371ef75-d9ea-4103-bcfa-2da973ddec1b\" = true\n\n# ending with whitespace\n\"05b304d6-f83b-46e7-81e0-4cd3ca647900\" = true\n\n# other whitespace\n\"72bd5ad3-9b2f-4931-a988-dce1f5771de2\" = true\n\n# non-question ending with whitespace\n\"12983553-8601-46a8-92fa-fcaa3bc4a2a0\" = true\n"
  },
  {
    "path": "exercises/practice/bob/.meta/version",
    "content": "1.4.0\n"
  },
  {
    "path": "exercises/practice/bob/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bob/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/bob/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/bob/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/bob/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bob/src/main/kotlin/Bob.kt",
    "content": "object Bob {\n    fun hey(input: String): String {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bob/src/test/kotlin/BobTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass BobTest {\n\n    @Test\n    fun statingSomething() {\n        assertEquals(\"Whatever.\", Bob.hey(\"Tom-ay-to, tom-aaaah-to.\"))\n    }\n\n    @Ignore\n    @Test\n    fun shouting() {\n        assertEquals(\"Whoa, chill out!\", Bob.hey(\"WATCH OUT!\"))\n    }\n\n    @Ignore\n    @Test\n    fun shoutingGibberish() {\n        assertEquals(\"Whoa, chill out!\", Bob.hey(\"FCECDFCAAB\"))\n    }\n\n    @Ignore\n    @Test\n    fun askingAQuestion() {\n        assertEquals(\"Sure.\", Bob.hey(\"Does this cryogenic chamber make me look fat?\"))\n    }\n\n    @Ignore\n    @Test\n    fun askingANumericQuestion() {\n        assertEquals(\"Sure.\", Bob.hey(\"You are, what, like 15?\"))\n    }\n\n    @Ignore\n    @Test\n    fun askingGibberish() {\n        assertEquals(\"Sure.\", Bob.hey(\"fffbbcbeab?\"))\n    }\n\n    @Ignore\n    @Test\n    fun talkingForcefully() {\n        assertEquals(\"Whatever.\", Bob.hey(\"Let's go make out behind the gym!\"))\n    }\n\n    @Ignore\n    @Test\n    fun usingAcronymsInRegularSpeech() {\n        assertEquals(\"Whatever.\", Bob.hey(\"It's OK if you don't want to go to the DMV.\"))\n    }\n\n    @Ignore\n    @Test\n    fun forcefulQuestion() {\n        assertEquals(\"Calm down, I know what I'm doing!\", Bob.hey(\"WHAT THE HELL WERE YOU THINKING?\"))\n    }\n\n    @Ignore\n    @Test\n    fun shoutingNumbers() {\n        assertEquals(\"Whoa, chill out!\", Bob.hey(\"1, 2, 3 GO!\"))\n    }\n\n    @Ignore\n    @Test\n    fun noLetters() {\n        assertEquals(\"Whatever.\", Bob.hey(\"1, 2, 3\"))\n    }\n\n    @Ignore\n    @Test\n    fun questionWithNoLetters() {\n        assertEquals(\"Sure.\", Bob.hey(\"4?\"))\n    }\n\n    @Ignore\n    @Test\n    fun shoutingWithSpecialCharacters() {\n        assertEquals(\"Whoa, chill out!\", Bob.hey(\"ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!\"))\n    }\n\n    @Ignore\n    @Test\n    fun shoutingWithNoExclamationMark() {\n        assertEquals(\"Whoa, chill out!\", Bob.hey(\"I HATE THE DMV\"))\n    }\n\n    @Ignore\n    @Test\n    fun statementContainingQuestionMark() {\n        assertEquals(\"Whatever.\", Bob.hey(\"Ending with ? means a question.\"))\n    }\n\n    @Ignore\n    @Test\n    fun nonLettersWithQuestion() {\n        assertEquals(\"Sure.\", Bob.hey(\":) ?\"))\n    }\n\n    @Ignore\n    @Test\n    fun prattlingOn() {\n        assertEquals(\"Sure.\", Bob.hey(\"Wait! Hang on. Are you going to be OK?\"))\n    }\n\n    @Ignore\n    @Test\n    fun silence() {\n        assertEquals(\"Fine. Be that way!\", Bob.hey(\"\"))\n    }\n\n    @Ignore\n    @Test\n    fun prolongedSilence() {\n        assertEquals(\"Fine. Be that way!\", Bob.hey(\"          \"))\n    }\n\n    @Ignore\n    @Test\n    fun alternateSilence() {\n        assertEquals(\"Fine. Be that way!\", Bob.hey(\"\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\"))\n    }\n\n    @Ignore\n    @Test\n    fun multipleLineQuestion() {\n        assertEquals(\"Whatever.\", Bob.hey(\"\\nDoes this cryogenic chamber make me look fat?\\nno\"))\n    }\n\n    @Ignore\n    @Test\n    fun startingWithWhitespace() {\n        assertEquals(\"Whatever.\", Bob.hey(\"         hmmmmmmm...\"))\n    }\n\n    @Ignore\n    @Test\n    fun endingWithWhitespace() {\n        assertEquals(\"Sure.\", Bob.hey(\"Okay if like my  spacebar  quite a bit?   \"))\n    }\n\n    @Ignore\n    @Test\n    fun otherWhitespace() {\n        assertEquals(\"Fine. Be that way!\", Bob.hey(\"\\n\\r \\t\"))\n    }\n\n    @Ignore\n    @Test\n    fun nonQuestionEndingWithWhitespace() {\n        assertEquals(\"Whatever.\", Bob.hey(\"This is a statement ending with whitespace      \"))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/bottle-song/.docs/instructions.md",
    "content": "# Instructions\n\nRecite the lyrics to that popular children's repetitive song: Ten Green Bottles.\n\nNote that not all verses are identical.\n\n```text\nTen green bottles hanging on the wall,\nTen green bottles hanging on the wall,\nAnd if one green bottle should accidentally fall,\nThere'll be nine green bottles hanging on the wall.\n\nNine green bottles hanging on the wall,\nNine green bottles hanging on the wall,\nAnd if one green bottle should accidentally fall,\nThere'll be eight green bottles hanging on the wall.\n\nEight green bottles hanging on the wall,\nEight green bottles hanging on the wall,\nAnd if one green bottle should accidentally fall,\nThere'll be seven green bottles hanging on the wall.\n\nSeven green bottles hanging on the wall,\nSeven green bottles hanging on the wall,\nAnd if one green bottle should accidentally fall,\nThere'll be six green bottles hanging on the wall.\n\nSix green bottles hanging on the wall,\nSix green bottles hanging on the wall,\nAnd if one green bottle should accidentally fall,\nThere'll be five green bottles hanging on the wall.\n\nFive green bottles hanging on the wall,\nFive green bottles hanging on the wall,\nAnd if one green bottle should accidentally fall,\nThere'll be four green bottles hanging on the wall.\n\nFour green bottles hanging on the wall,\nFour green bottles hanging on the wall,\nAnd if one green bottle should accidentally fall,\nThere'll be three green bottles hanging on the wall.\n\nThree green bottles hanging on the wall,\nThree green bottles hanging on the wall,\nAnd if one green bottle should accidentally fall,\nThere'll be two green bottles hanging on the wall.\n\nTwo green bottles hanging on the wall,\nTwo green bottles hanging on the wall,\nAnd if one green bottle should accidentally fall,\nThere'll be one green bottle hanging on the wall.\n\nOne green bottle hanging on the wall,\nOne green bottle hanging on the wall,\nAnd if one green bottle should accidentally fall,\nThere'll be no green bottles hanging on the wall.\n```\n"
  },
  {
    "path": "exercises/practice/bottle-song/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"kahgoh\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/BottleSong.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/BottleSongTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/BottleSong.kt\"\n    ]\n  },\n  \"blurb\": \"Produce the lyrics to the popular children's repetitive song: Ten Green Bottles.\",\n  \"source\": \"Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Ten_Green_Bottles\"\n}\n"
  },
  {
    "path": "exercises/practice/bottle-song/.meta/src/reference/kotlin/BottleSong.kt",
    "content": "object BottleSong {\n    fun recite(startBottles : Int, takeDown : Int) : String {\n        return (0..(takeDown - 1))\n            .joinToString(separator = \"\\n\\n\") {\n                verse(startBottles - it)\n            }\n    }\n\n    private fun verse(bottles : Int) : String {\n        val start = verseStart(bottles)\n        return \"\"\"\n            $start\n            $start\n            And if one green bottle should accidentally fall,\n            ${verseEnd(bottles - 1)}\n        \"\"\".trimIndent()\n    }\n\n    private fun verseStart(bottles : Int) : String {\n        return if (bottles > 1) {\n            \"${toWord(bottles)} green bottles hanging on the wall,\"\n        } else {\n            \"One green bottle hanging on the wall,\"\n        }\n    }\n\n    private fun verseEnd(bottles : Int) : String {\n        return when(bottles) {\n            0 -> \"There'll be no green bottles hanging on the wall.\"\n            1 -> \"There'll be ${toWord(bottles).lowercase()} green bottle hanging on the wall.\"\n            else -> \"There'll be ${toWord(bottles).lowercase()} green bottles hanging on the wall.\"\n        }\n    }\n\n    private fun toWord(num : Int) : String {\n        return when(num) {\n            1 -> \"One\"\n            2 -> \"Two\"\n            3 -> \"Three\"\n            4 -> \"Four\"\n            5 -> \"Five\"\n            6 -> \"Six\"\n            7 -> \"Seven\"\n            8 -> \"Eight\"\n            9 -> \"Nine\"\n            10 -> \"Ten\"\n            else -> throw IllegalArgumentException(\"Number $num not supported\")\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bottle-song/.meta/tests.toml",
    "content": "# This is an auto-generated file.\n#\n# Regenerating this file via `configlet sync` will:\n# - Recreate every `description` key/value pair\n# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications\n# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)\n# - Preserve any other key/value pair\n#\n# As user-added comments (using the # character) will be removed when this file\n# is regenerated, comments can be added via a `comment` key.\n\n[d4ccf8fc-01dc-48c0-a201-4fbeb30f2d03]\ndescription = \"verse -> single verse -> first generic verse\"\n\n[0f0aded3-472a-4c64-b842-18d4f1f5f030]\ndescription = \"verse -> single verse -> last generic verse\"\n\n[f61f3c97-131f-459e-b40a-7428f3ed99d9]\ndescription = \"verse -> single verse -> verse with 2 bottles\"\n\n[05eadba9-5dbd-401e-a7e8-d17cc9baa8e0]\ndescription = \"verse -> single verse -> verse with 1 bottle\"\n\n[a4a28170-83d6-4dc1-bd8b-319b6abb6a80]\ndescription = \"lyrics -> multiple verses -> first two verses\"\n\n[3185d438-c5ac-4ce6-bcd3-02c9ff1ed8db]\ndescription = \"lyrics -> multiple verses -> last three verses\"\n\n[28c1584a-0e51-4b65-9ae2-fbc0bf4bbb28]\ndescription = \"lyrics -> multiple verses -> all verses\"\n"
  },
  {
    "path": "exercises/practice/bottle-song/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bottle-song/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/bottle-song/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/bottle-song/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/bottle-song/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bottle-song/src/main/kotlin/BottleSong.kt",
    "content": "object BottleSong {\n    fun recite(startBottles : Int, takeDown : Int) : String {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bottle-song/src/test/kotlin/BottleSongTest.kt",
    "content": "import org.junit.experimental.runners.Enclosed\nimport org.junit.runner.RunWith\nimport kotlin.test.Ignore\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\n\nclass BottleSongTest {\n\n    @Test\n    fun `single verse`() {\n        val expected = \"\"\"\n            Ten green bottles hanging on the wall,\n            Ten green bottles hanging on the wall,\n            And if one green bottle should accidentally fall,\n            There'll be nine green bottles hanging on the wall.\n        \"\"\".trimIndent()\n        assertEquals(expected, BottleSong.recite(10, 1))\n    }\n\n    @Ignore\n    @Test\n    fun `last generic verse`() {\n        val expected = \"\"\"\n            Three green bottles hanging on the wall,\n            Three green bottles hanging on the wall,\n            And if one green bottle should accidentally fall,\n            There'll be two green bottles hanging on the wall.\n        \"\"\".trimIndent()\n        assertEquals(expected, BottleSong.recite(3, 1))\n    }\n\n    @Ignore\n    @Test\n    fun `verse with 2 bottles`() {\n        val expected =\n            \"\"\"\n            Two green bottles hanging on the wall,\n            Two green bottles hanging on the wall,\n            And if one green bottle should accidentally fall,\n            There'll be one green bottle hanging on the wall.\n        \"\"\".trimIndent()\n        assertEquals(\n            expected, BottleSong.recite(2, 1)\n        )\n\n    }\n\n    @Ignore\n    @Test\n    fun `verse with 1 bottle`() {\n        val expected =\n            \"\"\"\n                One green bottle hanging on the wall,\n                One green bottle hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be no green bottles hanging on the wall.\n        \"\"\".trimIndent()\n        assertEquals(\n            expected, BottleSong.recite(1, 1)\n        )\n    }\n\n    @Ignore\n    @Test\n    fun `multiple verses`() {\n        val expected =\n            \"\"\"\n                Ten green bottles hanging on the wall,\n                Ten green bottles hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be nine green bottles hanging on the wall.\n                \n                Nine green bottles hanging on the wall,\n                Nine green bottles hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be eight green bottles hanging on the wall.\n        \"\"\".trimIndent()\n        assertEquals(\n            expected, BottleSong.recite(10, 2)\n        )\n    }\n\n    @Ignore\n    @Test\n    fun `last three verses`() {\n        val expected =\n            \"\"\"\n                Three green bottles hanging on the wall,\n                Three green bottles hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be two green bottles hanging on the wall.\n                \n                Two green bottles hanging on the wall,\n                Two green bottles hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be one green bottle hanging on the wall.\n                \n                One green bottle hanging on the wall,\n                One green bottle hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be no green bottles hanging on the wall.\n        \"\"\".trimIndent()\n        assertEquals(\n            expected, BottleSong.recite(3, 3)\n        )\n    }\n\n    @Ignore\n    @Test\n    fun `all verses`() {\n        val expected =\n            \"\"\"\n                Ten green bottles hanging on the wall,\n                Ten green bottles hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be nine green bottles hanging on the wall.\n                \n                Nine green bottles hanging on the wall,\n                Nine green bottles hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be eight green bottles hanging on the wall.\n                \n                Eight green bottles hanging on the wall,\n                Eight green bottles hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be seven green bottles hanging on the wall.\n                \n                Seven green bottles hanging on the wall,\n                Seven green bottles hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be six green bottles hanging on the wall.\n                \n                Six green bottles hanging on the wall,\n                Six green bottles hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be five green bottles hanging on the wall.\n                \n                Five green bottles hanging on the wall,\n                Five green bottles hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be four green bottles hanging on the wall.\n                \n                Four green bottles hanging on the wall,\n                Four green bottles hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be three green bottles hanging on the wall.\n                \n                Three green bottles hanging on the wall,\n                Three green bottles hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be two green bottles hanging on the wall.\n                \n                Two green bottles hanging on the wall,\n                Two green bottles hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be one green bottle hanging on the wall.\n                \n                One green bottle hanging on the wall,\n                One green bottle hanging on the wall,\n                And if one green bottle should accidentally fall,\n                There'll be no green bottles hanging on the wall.\n        \"\"\".trimIndent()\n        assertEquals(\n            expected, BottleSong.recite(10, 10)\n        )\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bowling/.docs/instructions.md",
    "content": "# Instructions\n\nScore a bowling game.\n\nBowling is a game where players roll a heavy ball to knock down pins arranged in a triangle.\nWrite code to keep track of the score of a game of bowling.\n\n## Scoring Bowling\n\nThe game consists of 10 frames.\nA frame is composed of one or two ball throws with 10 pins standing at frame initialization.\nThere are three cases for the tabulation of a frame.\n\n- An open frame is where a score of less than 10 is recorded for the frame.\n  In this case the score for the frame is the number of pins knocked down.\n\n- A spare is where all ten pins are knocked down by the second throw.\n  The total value of a spare is 10 plus the number of pins knocked down in their next throw.\n\n- A strike is where all ten pins are knocked down by the first throw.\n  The total value of a strike is 10 plus the number of pins knocked down in the next two throws.\n  If a strike is immediately followed by a second strike, then the value of the first strike cannot be determined until the ball is thrown one more time.\n\nHere is a three frame example:\n\n|  Frame 1   |  Frame 2   |     Frame 3      |\n| :--------: | :--------: | :--------------: |\n| X (strike) | 5/ (spare) | 9 0 (open frame) |\n\nFrame 1 is (10 + 5 + 5) = 20\n\nFrame 2 is (5 + 5 + 9) = 19\n\nFrame 3 is (9 + 0) = 9\n\nThis means the current running total is 48.\n\nThe tenth frame in the game is a special case.\nIf someone throws a spare or a strike then they get one or two fill balls respectively.\nFill balls exist to calculate the total of the 10th frame.\nScoring a strike or spare on the fill ball does not give the player more fill balls.\nThe total value of the 10th frame is the total number of pins knocked down.\n\nFor a tenth frame of X1/ (strike and a spare), the total value is 20.\n\nFor a tenth frame of XXX (three strikes), the total value is 30.\n\n## Requirements\n\nWrite code to keep track of the score of a game of bowling.\nIt should support two operations:\n\n- `roll(pins : int)` is called each time the player rolls a ball.\n  The argument is the number of pins knocked down.\n- `score() : int` is called only at the very end of the game.\n  It returns the total score for that game.\n"
  },
  {
    "path": "exercises/practice/bowling/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"vmichalak\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/BowlingGame.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/BowlingGameTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/BowlingGame.kt\"\n    ]\n  },\n  \"blurb\": \"Score a bowling game.\",\n  \"source\": \"The Bowling Game Kata from UncleBob\",\n  \"source_url\": \"https://web.archive.org/web/20221001111000/http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata\"\n}\n"
  },
  {
    "path": "exercises/practice/bowling/.meta/src/reference/kotlin/BowlingGame.kt",
    "content": "class BowlingGame {\n    private var builder = Frame.Builder()\n    private val frames = mutableListOf<Frame>()\n\n    private val isLastFrame: Boolean\n        get() = frames.size == 11 || (frames.size == 10 && !frames[9].isStrike)\n\n    private val isGameOver: Boolean\n        get() = when {\n            frames.size < 10 -> false\n            frames.size == 10 -> !frames[9].isSpare\n            frames.size == 11 -> !frames[9].isStrike || !frames[10].isStrike\n            else -> true\n        }\n\n    fun roll(pins: Int) {\n        if(isGameOver) {\n            throw IllegalStateException(\"Cannot roll after game is over\")\n        }\n        builder.withRoll(pins);\n        if (builder.isComplete) {\n            frames.add(builder.build());\n            builder = Frame.Builder();\n        } else if (isLastFrame) {\n            frames.add(builder.build());\n        }\n    }\n\n    fun score(): Int {\n        if(!isGameOver) {\n            throw IllegalStateException(\"Score cannot be taken until the end of the game\")\n        }\n        return (0 until 10).sumOf { index ->\n            val current = frames[index]\n            val next = frames.getOrElse(index + 1) { Frame.EMPTY }\n            val nextNext = frames.getOrElse(index + 2) { Frame.EMPTY }\n            current.score(next, nextNext)\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bowling/.meta/src/reference/kotlin/Frame.kt",
    "content": "class Frame(val first: Int, val second: Int) {\n    companion object {\n        val EMPTY = Frame(0, 0)\n    }\n\n    val frameScore: Int\n        get() = first + second\n\n    val isStrike: Boolean\n        get() = (first == 10)\n\n    val isSpare: Boolean\n        get() = (frameScore == 10)\n\n    fun score(next: Frame, nextNext: Frame) = frameScore + when {\n        isStrike -> nextNextRoll(next, nextNext) + next.first\n        isSpare -> next.first\n        else -> 0\n    }\n\n    private fun nextNextRoll(next: Frame, nextNext: Frame) =\n        if(next.isStrike) { nextNext.first } else { next.second }\n\n    class Builder {\n        private val rolls = mutableListOf<Int>()\n\n        val count: Int\n            get() = rolls.sum()\n\n        val isStrike: Boolean\n            get() = rolls.size == 1 && rolls[0] == 10\n\n        val isComplete: Boolean\n            get() = rolls.size == 2 || isStrike\n\n        fun withRoll(pins: Int): Builder {\n            if(isComplete) { throw IllegalStateException(\"Frame complete\") }\n            if(pins < 0) { throw IllegalStateException(\"Negative roll is invalid\") }\n            if(count + pins > 10) { throw IllegalStateException(\"Pin count exceeds pins on the lane\") }\n            rolls.add(pins)\n            return this\n        }\n\n        public fun build(): Frame = when (rolls.size) {\n            2 -> Frame(rolls[0], rolls[1])\n            1 -> Frame(rolls[0], 0)\n            else -> throw AssertionError(\"Frame has invalid number of rolls: \" + rolls.size)\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bowling/.meta/version",
    "content": "1.0.0\n"
  },
  {
    "path": "exercises/practice/bowling/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bowling/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/bowling/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/bowling/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/bowling/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bowling/src/main/kotlin/BowlingGame.kt",
    "content": "class BowlingGame {\n    fun roll(pins: Int) {\n        TODO(\"Implement the function to complete the task\")\n    }\n\n    fun score() {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/bowling/src/test/kotlin/BowlingGameTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Rule\nimport org.junit.rules.ExpectedException\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\n\nclass BowlingGameTest {\n\n    @Rule\n    @JvmField\n    var expectedException: ExpectedException = ExpectedException.none()\n\n    private fun playGame(rolls: IntArray): BowlingGame {\n        val game = BowlingGame()\n        rolls.forEach {\n            game.roll(it)\n        }\n        return game\n    }\n\n    @Test\n    fun `should be able to score a game with all zeros`() {\n        val game = playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))\n        assertEquals(0, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `should be able to score a game with no strike or spares`() {\n        val game = playGame(intArrayOf(3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6))\n        assertEquals(90, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `a spare followed by zeros is worth ten points`() {\n        val game = playGame(intArrayOf(6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))\n        assertEquals(10, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `points scored in the roll after a spare are counted twice`() {\n        val game = playGame(intArrayOf(6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))\n        assertEquals(16, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `consecutive spares each get a one roll bonus`() {\n        val game = playGame(intArrayOf(5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))\n        assertEquals(31, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `a spare in the last frame gets a one roll bonus that is counted once`() {\n        val game = playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7))\n        assertEquals(17, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `a strike earns ten points in frame with a single roll`() {\n        val game = playGame(intArrayOf(10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))\n        assertEquals(10, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `points scored in the two rolls after a strike are counted twice as a bonus`() {\n        val game = playGame(intArrayOf(10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))\n        assertEquals(26, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `consecutive strikes each get the two roll bonus`() {\n        val game = playGame(intArrayOf(10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))\n        assertEquals(81, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `a strike in the last frame gets a two roll bonus that is counted once`() {\n        val game = playGame(intArrayOf(10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))\n        assertEquals(81, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `rolling a spare with the two roll bonus does not get a bonus roll`() {\n        val game = playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3))\n        assertEquals(20, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `strikes with the two roll bonus do not get bonus rolls`() {\n        val game = playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10))\n        assertEquals(30, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `last two strikes followed by only last bonus with non strike points`() {\n        val game = playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 0, 1))\n        assertEquals(31, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `a strike with the one roll bonus after a spare in the last frame does not get a bonus`() {\n        val game = playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10))\n        assertEquals(20, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `all strikes is a perfect game`() {\n        val game = playGame(intArrayOf(10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10))\n        assertEquals(300, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `rolls can not score negative points`() {\n        expectedException.expect(IllegalStateException::class.java)\n\n        playGame(intArrayOf(-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))\n    }\n\n    @Test\n    @Ignore\n    fun `a roll can not score more than 10 points`() {\n        expectedException.expect(IllegalStateException::class.java)\n\n        playGame(intArrayOf(11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))\n    }\n\n    @Test\n    @Ignore\n    fun `two rolls in a frame can not score more than 10 points`() {\n        expectedException.expect(IllegalStateException::class.java)\n\n        playGame(intArrayOf(5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))\n    }\n\n    @Test\n    @Ignore\n    fun `bonus roll after a strike in the last frame can not score more than 10 points`() {\n        expectedException.expect(IllegalStateException::class.java)\n\n        playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 0))\n    }\n\n    @Test\n    @Ignore\n    fun `two bonus rolls after a strike in the last frame can not score more than 10 points`() {\n        expectedException.expect(IllegalStateException::class.java)\n\n        playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6))\n    }\n\n    @Test\n    @Ignore\n    fun `two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike`() {\n        val game = playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 6))\n        assertEquals(26, game.score())\n    }\n\n    @Test\n    @Ignore\n    fun `the second bonus rolls after a strike in the last frame can not be a strike if the first one is not a strike`() {\n        expectedException.expect(IllegalStateException::class.java)\n\n        playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6, 10))\n    }\n\n    @Test\n    @Ignore\n    fun `second bonus roll after a strike in the last frame can not score more than 10 points`() {\n        expectedException.expect(IllegalStateException::class.java)\n\n        playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 11))\n    }\n\n    @Test\n    @Ignore\n    fun `an unstarted game can not be scored`() {\n        expectedException.expect(IllegalStateException::class.java)\n\n        playGame(intArrayOf()).score()\n    }\n\n    @Test\n    @Ignore\n    fun `an incomplete game can not be scored`() {\n        expectedException.expect(IllegalStateException::class.java)\n\n        playGame(intArrayOf(0, 0, 1)).score()\n    }\n\n    @Test\n    @Ignore\n    fun `can not roll if game already has ten frames`() {\n        expectedException.expect(IllegalStateException::class.java)\n\n        playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))\n    }\n\n    @Test\n    @Ignore\n    fun `bonus rolls for a strike in the last frame must be rolled before score can be calculated`() {\n        expectedException.expect(IllegalStateException::class.java)\n\n        playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10)).score()\n    }\n\n    @Test\n    @Ignore\n    fun `both bonus rolls for a strike in the last frame must be rolled before score can be calculated`() {\n        expectedException.expect(IllegalStateException::class.java)\n\n        playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10)).score()\n    }\n\n    @Test\n    @Ignore\n    fun `bonus roll for a spare in the last frame must be rolled before score can be calculated`() {\n        expectedException.expect(IllegalStateException::class.java)\n\n        playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3)).score()\n    }\n\n    @Test\n    @Ignore\n    fun `can not roll after bonus roll for spare`() {\n        expectedException.expect(IllegalStateException::class.java)\n\n        playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 2, 2)).score()\n    }\n\n    @Test\n    @Ignore\n    fun `can not roll after bonus roll for strike`() {\n        expectedException.expect(IllegalStateException::class.java)\n\n        playGame(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 2, 2)).score()\n    }\n}\n"
  },
  {
    "path": "exercises/practice/change/.docs/instructions.md",
    "content": "# Instructions\n\nDetermine the fewest number of coins to give a customer so that the sum of their values equals the correct amount of change.\n\n## Examples\n\n- An amount of 15 with available coin values [1, 5, 10, 25, 100] should return one coin of value 5 and one coin of value 10, or [5, 10].\n- An amount of 40 with available coin values [1, 5, 10, 25, 100] should return one coin of value 5, one coin of value 10, and one coin of value 25, or [5, 10, 25].\n"
  },
  {
    "path": "exercises/practice/change/.docs/introduction.md",
    "content": "# Introduction\n\nIn the mystical village of Coinholt, you stand behind the counter of your bakery, arranging a fresh batch of pastries.\nThe door creaks open, and in walks Denara, a skilled merchant with a keen eye for quality goods.\nAfter a quick meal, she slides a shimmering coin across the counter, representing a value of 100 units.\n\nYou smile, taking the coin, and glance at the total cost of the meal: 88 units.\nThat means you need to return 12 units in change.\n\nDenara holds out her hand expectantly.\n\"Just give me the fewest coins,\" she says with a smile.\n\"My pouch is already full, and I don't want to risk losing them on the road.\"\n\nYou know you have a few options.\n\"We have Lumis (worth 10 units), Viras (worth 5 units), and Zenth (worth 2 units) available for change.\"\n\nYou quickly calculate the possibilities in your head:\n\n- one Lumis (1 × 10 units) + one Zenth (1 × 2 units) = 2 coins total\n- two Viras (2 × 5 units) + one Zenth (1 × 2 units) = 3 coins total\n- six Zenth (6 × 2 units) = 6 coins total\n\n\"The best choice is two coins: one Lumis and one Zenth,\" you say, handing her the change.\n\nDenara smiles, clearly impressed.\n\"As always, you've got it right.\"\n"
  },
  {
    "path": "exercises/practice/change/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"geoand\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/ChangeCalculator.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ChangeCalculatorTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/ChangeCalculator.kt\"\n    ]\n  },\n  \"blurb\": \"Correctly determine change to be given using the least number of coins.\",\n  \"source\": \"Software Craftsmanship - Coin Change Kata\",\n  \"source_url\": \"https://web.archive.org/web/20130115115225/http://craftsmanship.sv.cmu.edu:80/exercises/coin-change-kata\"\n}\n"
  },
  {
    "path": "exercises/practice/change/.meta/src/reference/kotlin/ChangeCalculator.kt",
    "content": "class ChangeCalculator(coins: List<Int>) {\n\n    private val sortedCoins = coins.sorted()\n\n    fun computeMostEfficientChange(grandTotal: Int): List<Int> {\n        require(grandTotal >= 0) { \"Negative totals are not allowed.\" }\n\n        val minimalCoinsMap = mutableMapOf<Int, List<Int>?>()\n        minimalCoinsMap[0] = ArrayList()\n\n        for (total in 1..grandTotal) {\n            val minimalCoins = sortedCoins\n                .filter { it <= total }\n                .mapNotNull { coin ->\n                    val minimalRemainderCoins = minimalCoinsMap[total - coin]\n                    if (minimalRemainderCoins != null) prepend(coin, minimalRemainderCoins) else null\n                }.minByOrNull { it.size }\n\n            minimalCoinsMap[total] = minimalCoins\n        }\n\n        return minimalCoinsMap[grandTotal] ?: throw IllegalArgumentException(\n                \"The total $grandTotal cannot be represented in the given currency.\")\n    }\n\n    private fun prepend(integer: Int, integers: List<Int>): List<Int> {\n        val result = mutableListOf<Int>()\n        result.add(integer)\n        result.addAll(integers)\n        return result\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/change/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# single coin change\n\"36887bea-7f92-4a9c-b0cc-c0e886b3ecc8\" = true\n\n# multiple coin change\n\"cef21ccc-0811-4e6e-af44-f011e7eab6c6\" = true\n\n# change with Lilliputian Coins\n\"d60952bc-0c1a-4571-bf0c-41be72690cb3\" = true\n\n# change with Lower Elbonia Coins\n\"408390b9-fafa-4bb9-b608-ffe6036edb6c\" = true\n\n# large target values\n\"7421a4cb-1c48-4bf9-99c7-7f049689132f\" = true\n\n# possible change without unit coins available\n\"f79d2e9b-0ae3-4d6a-bb58-dc978b0dba28\" = true\n\n# another possible change without unit coins available\n\"9a166411-d35d-4f7f-a007-6724ac266178\" = true\n\n# no coins make 0 change\n\"bbbcc154-e9e9-4209-a4db-dd6d81ec26bb\" = true\n\n# error testing for change smaller than the smallest of coins\n\"c8b81d5a-49bd-4b61-af73-8ee5383a2ce1\" = true\n\n# error if no combination can add up to target\n\"3c43e3e4-63f9-46ac-9476-a67516e98f68\" = true\n\n# cannot find negative change values\n\"8fe1f076-9b2d-4f44-89fe-8a6ccd63c8f3\" = true\n"
  },
  {
    "path": "exercises/practice/change/.meta/version",
    "content": "1.2.0\n"
  },
  {
    "path": "exercises/practice/change/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/change/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/change/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/change/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/change/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/change/src/main/kotlin/ChangeCalculator.kt",
    "content": "class ChangeCalculator {\n    // TODO: implement proper constructor\n\n    fun computeMostEfficientChange(grandTotal: Int): List<Int> {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/change/src/test/kotlin/ChangeCalculatorTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.rules.ExpectedException\nimport kotlin.test.assertEquals\n\nclass ChangeCalculatorTest {\n\n    @Rule\n    @JvmField\n    var expectedException: ExpectedException = ExpectedException.none()\n\n    @Test\n    fun singleCoinChange() {\n        val computedChange = ChangeCalculator(listOf(1, 5, 10, 25, 100)).computeMostEfficientChange(25)\n        assertContainsExactly(computedChange, listOf(25))\n    }\n\n    @Ignore\n    @Test\n    fun multipleCoinChange() {\n        val computedChange = ChangeCalculator(listOf(1, 5, 10, 25, 100)).computeMostEfficientChange(15)\n        assertContainsExactly(computedChange, listOf(5, 10))\n    }\n\n    @Ignore\n    @Test\n    fun changeWithLilliputianCoins() {\n        val computedChange = ChangeCalculator(listOf(1, 4, 15, 20, 50)).computeMostEfficientChange(23)\n        assertContainsExactly(computedChange, listOf(4, 4, 15))\n    }\n\n    @Ignore\n    @Test\n    fun changeWithLowerElboniaCoins() {\n        val computedChange = ChangeCalculator(listOf(1, 5, 10, 21, 25)).computeMostEfficientChange(63)\n        assertContainsExactly(computedChange, listOf(21, 21, 21))\n    }\n\n    @Ignore\n    @Test\n    fun largeTargetValues() {\n        val computedChange = ChangeCalculator(listOf(1, 2, 5, 10, 20, 50, 100)).computeMostEfficientChange(999)\n        assertContainsExactly(computedChange,\n            listOf(2, 2, 5, 20, 20, 50, 100, 100, 100, 100, 100, 100, 100, 100, 100))\n    }\n\n    @Ignore\n    @Test\n    fun possibleChangeWithoutUnitCoinsAvailable() {\n        val computedChange = ChangeCalculator(listOf(2, 5, 10, 20, 50)).computeMostEfficientChange(21)\n        assertContainsExactly(computedChange, listOf(2, 2, 2, 5, 10))\n    }\n\n    @Ignore\n    @Test\n    fun anotherPossibleChangeWithoutUnitCoinsAvailable() {\n        val computedChange = ChangeCalculator(listOf(4, 5)).computeMostEfficientChange(27)\n        assertContainsExactly(computedChange, listOf(4, 4, 4, 5, 5, 5))\n    }\n\n    @Ignore\n    @Test\n    fun noCoinsMake0Change() {\n        val computedChange = ChangeCalculator(listOf(1, 5, 10, 21, 25)).computeMostEfficientChange(0)\n        assertEquals(0, computedChange.size)\n    }\n\n    @Ignore\n    @Test\n    fun errorTestingForChangeSmallerThanTheSmallestCoin() {\n        val changeCalculator = ChangeCalculator(listOf(5, 10))\n\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"The total 3 cannot be represented in the given currency.\")\n\n        changeCalculator.computeMostEfficientChange(3)\n    }\n\n    @Ignore\n    @Test\n    fun errorIfNoCombinationCanAddUpToTarget() {\n        val changeCalculator = ChangeCalculator(listOf(5, 10))\n\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"The total 94 cannot be represented in the given currency.\")\n\n        changeCalculator.computeMostEfficientChange(94)\n    }\n\n    @Ignore\n    @Test\n    fun cannotFindNegativeChangeValues() {\n        val changeCalculator = ChangeCalculator(listOf(1, 2, 5))\n\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"Negative totals are not allowed.\")\n\n        changeCalculator.computeMostEfficientChange(-5)\n    }\n\n}\n\nprivate inline fun <reified T> assertContainsExactly(actualList: List<T>, expectedValues: List<T>) {\n    assertEquals(expectedValues.size, actualList.size)\n    expectedValues.forEach { actualList.contains(it) }\n}\n"
  },
  {
    "path": "exercises/practice/circular-buffer/.docs/instructions.md",
    "content": "# Instructions\n\nA circular buffer, cyclic buffer or ring buffer is a data structure that uses a single, fixed-size buffer as if it were connected end-to-end.\n\nA circular buffer first starts empty and of some predefined length.\nFor example, this is a 7-element buffer:\n\n```text\n[ ][ ][ ][ ][ ][ ][ ]\n```\n\nAssume that a 1 is written into the middle of the buffer (exact starting location does not matter in a circular buffer):\n\n```text\n[ ][ ][ ][1][ ][ ][ ]\n```\n\nThen assume that two more elements are added — 2 & 3 — which get appended after the 1:\n\n```text\n[ ][ ][ ][1][2][3][ ]\n```\n\nIf two elements are then removed from the buffer, the oldest values inside the buffer are removed.\nThe two elements removed, in this case, are 1 & 2, leaving the buffer with just a 3:\n\n```text\n[ ][ ][ ][ ][ ][3][ ]\n```\n\nIf the buffer has 7 elements then it is completely full:\n\n```text\n[5][6][7][8][9][3][4]\n```\n\nWhen the buffer is full an error will be raised, alerting the client that further writes are blocked until a slot becomes free.\n\nWhen the buffer is full, the client can opt to overwrite the oldest data with a forced write.\nIn this case, two more elements — A & B — are added and they overwrite the 3 & 4:\n\n```text\n[5][6][7][8][9][A][B]\n```\n\n3 & 4 have been replaced by A & B making 5 now the oldest data in the buffer.\nFinally, if two elements are removed then what would be returned is 5 & 6 yielding the buffer:\n\n```text\n[ ][ ][7][8][9][A][B]\n```\n\nBecause there is space available, if the client again uses overwrite to store C & D then the space where 5 & 6 were stored previously will be used not the location of 7 & 8.\n7 is still the oldest element and the buffer is once again full.\n\n```text\n[C][D][7][8][9][A][B]\n```\n"
  },
  {
    "path": "exercises/practice/circular-buffer/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"kahgoh\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/CircularBuffer.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/CircularBufferTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/CircularBuffer.kt\"\n    ]\n  },\n  \"blurb\": \"A data structure that uses a single, fixed-size buffer as if it were connected end-to-end.\",\n  \"source\": \"Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Circular_buffer\"\n}\n"
  },
  {
    "path": "exercises/practice/circular-buffer/.meta/src/reference/kotlin/CircularBuffer.kt",
    "content": "import kotlin.collections.ArrayDeque\n\nclass EmptyBufferException : Exception(\"Buffer is empty\") {}\n\nclass BufferFullException : Exception(\"Buffer is full\") {}\n\nclass CircularBuffer<T>(private val capacity: Int) {\n\n    private val contents = ArrayDeque<T>(capacity)\n\n    fun read() : T {\n        if (contents.isNotEmpty()) {\n            return contents.removeFirst()\n        }\n        throw EmptyBufferException()\n    }\n\n    fun write(value: T) {\n        if (contents.size < capacity) {\n            contents.add(value)\n        } else {\n            throw BufferFullException()\n        }\n    }\n\n    fun overwrite(value: T) {\n        if (contents.size >= capacity) {\n            contents.removeFirst()\n        }\n        contents.add(value)\n    }\n\n    fun clear() {\n        contents.clear()\n    }\n}"
  },
  {
    "path": "exercises/practice/circular-buffer/.meta/tests.toml",
    "content": "# This is an auto-generated file.\n#\n# Regenerating this file via `configlet sync` will:\n# - Recreate every `description` key/value pair\n# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications\n# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)\n# - Preserve any other key/value pair\n#\n# As user-added comments (using the # character) will be removed when this file\n# is regenerated, comments can be added via a `comment` key.\n\n[28268ed4-4ff3-45f3-820e-895b44d53dfa]\ndescription = \"reading empty buffer should fail\"\n\n[2e6db04a-58a1-425d-ade8-ac30b5f318f3]\ndescription = \"can read an item just written\"\n\n[90741fe8-a448-45ce-be2b-de009a24c144]\ndescription = \"each item may only be read once\"\n\n[be0e62d5-da9c-47a8-b037-5db21827baa7]\ndescription = \"items are read in the order they are written\"\n\n[2af22046-3e44-4235-bfe6-05ba60439d38]\ndescription = \"full buffer can't be written to\"\n\n[547d192c-bbf0-4369-b8fa-fc37e71f2393]\ndescription = \"a read frees up capacity for another write\"\n\n[04a56659-3a81-4113-816b-6ecb659b4471]\ndescription = \"read position is maintained even across multiple writes\"\n\n[60c3a19a-81a7-43d7-bb0a-f07242b1111f]\ndescription = \"items cleared out of buffer can't be read\"\n\n[45f3ae89-3470-49f3-b50e-362e4b330a59]\ndescription = \"clear frees up capacity for another write\"\n\n[e1ac5170-a026-4725-bfbe-0cf332eddecd]\ndescription = \"clear does nothing on empty buffer\"\n\n[9c2d4f26-3ec7-453f-a895-7e7ff8ae7b5b]\ndescription = \"overwrite acts like write on non-full buffer\"\n\n[880f916b-5039-475c-bd5c-83463c36a147]\ndescription = \"overwrite replaces the oldest item on full buffer\"\n\n[bfecab5b-aca1-4fab-a2b0-cd4af2b053c3]\ndescription = \"overwrite replaces the oldest item remaining in buffer following a read\"\n\n[9cebe63a-c405-437b-8b62-e3fdc1ecec5a]\ndescription = \"initial clear does not affect wrapping around\"\n"
  },
  {
    "path": "exercises/practice/circular-buffer/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/circular-buffer/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/circular-buffer/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/circular-buffer/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/circular-buffer/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/circular-buffer/src/main/kotlin/CircularBuffer.kt",
    "content": "import kotlin.collections.ArrayDeque\n\n// TODO: implement proper exceptions to complete the task\nclass EmptyBufferException\n\nclass BufferFullException\n\nclass CircularBuffer<T> {\n    // TODO: implement proper constructor to complete the task\n\n    fun read() : T {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun write(value: T) {\n        TODO(\"Implement this function to complete the task\")\n\n    }\n\n    fun overwrite(value: T) {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun clear() {\n        TODO(\"Implement this function to complete the task\")\n    }\n}"
  },
  {
    "path": "exercises/practice/circular-buffer/src/test/kotlin/CircularBufferTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\nimport kotlin.test.assertFailsWith\n\nclass CircularBufferTest {\n    @Test\n    fun `reading empty buffer should fail`() {\n        val buffer = CircularBuffer<Any>(1)\n        assertFailsWith<EmptyBufferException>() {\n            buffer.read()\n        }\n    }\n\n    @Ignore\n    @Test\n    fun `can read an item just written`() {\n        val buffer = CircularBuffer<Int>(1)\n        buffer.write(1)\n        assertEquals(1, buffer.read())\n    }\n\n    @Ignore\n    @Test\n    fun `each item may only be read once`() {\n        val buffer = CircularBuffer<Int>(1)\n        buffer.write(1)\n\n        assertEquals(1, buffer.read())\n        assertFailsWith<EmptyBufferException> {\n            buffer.read()\n        }\n    }\n\n    @Ignore\n    @Test\n    fun `items are read in the order they are written`() {\n        val buffer = CircularBuffer<Int>(2)\n        buffer.write(1)\n        buffer.write(2)\n\n        assertEquals(1, buffer.read())\n        assertEquals(2, buffer.read())\n    }\n\n    @Ignore\n    @Test\n    fun `full buffer can't be written to`() {\n        val buffer = CircularBuffer<Int>(1)\n        buffer.write(1)\n        assertFailsWith<BufferFullException> {\n            buffer.write(2)\n        }\n    }\n\n    @Ignore\n    @Test\n    fun `a read frees up capacity for another write`() {\n        val buffer = CircularBuffer<Int>(1)\n        buffer.write(1)\n        assertEquals(1, buffer.read())\n\n        buffer.write(2)\n        assertEquals(2, buffer.read())\n    }\n\n    @Ignore\n    @Test\n    fun `read position is maintained even across multiple writes`() {\n        val buffer = CircularBuffer<Int>(3)\n        buffer.write(1)\n        buffer.write(2)\n        assertEquals(1, buffer.read())\n\n        buffer.write(3)\n        assertEquals(2, buffer.read())\n        assertEquals(3, buffer.read())\n    }\n\n    @Ignore\n    @Test\n    fun `items cleared out of buffer can't be read`() {\n        val buffer = CircularBuffer<Int>(1)\n        buffer.write(1)\n        buffer.clear()\n\n        assertFailsWith<EmptyBufferException> {\n            buffer.read()\n        }\n    }\n\n    @Ignore\n    @Test\n    fun `clear frees up capacity for another write`() {\n        val buffer = CircularBuffer<Int>(1)\n        buffer.write(1)\n        buffer.clear()\n        buffer.write(2)\n\n        assertEquals(2, buffer.read())\n    }\n\n    @Ignore\n    @Test\n    fun `clear does nothing on empty buffer`() {\n        val buffer = CircularBuffer<Int>(1)\n        buffer.clear()\n        buffer.write(1)\n\n        assertEquals(1, buffer.read())\n    }\n\n    @Ignore\n    @Test\n    fun `overwrite acts like write on non-full buffer`() {\n        val buffer = CircularBuffer<Int>(2)\n        buffer.write(1)\n        buffer.overwrite(2)\n\n        assertEquals(1, buffer.read())\n        assertEquals(2, buffer.read())\n    }\n\n    @Ignore\n    @Test\n    fun `overwrite replaces the oldest item on full buffer`() {\n        val buffer = CircularBuffer<Int>(2)\n        buffer.write(1)\n        buffer.write(2)\n        buffer.overwrite(3)\n\n        assertEquals(2, buffer.read())\n        assertEquals(3, buffer.read())\n    }\n\n    @Ignore\n    @Test\n    fun `overwrite replaces the oldest item remaining in buffer following a read`() {\n        val buffer = CircularBuffer<Int>(3)\n        buffer.write(1)\n        buffer.write(2)\n        buffer.write(3)\n\n        assertEquals(1, buffer.read())\n        buffer.write(4)\n        buffer.overwrite(5)\n\n        assertEquals(3, buffer.read())\n        assertEquals(4, buffer.read())\n        assertEquals(5, buffer.read())\n    }\n\n    @Ignore\n    @Test\n    fun `initial clear does not affect wrapping around`() {\n        val buffer = CircularBuffer<Int>(2)\n        buffer.clear()\n        buffer.write(1)\n        buffer.write(2)\n        buffer.overwrite(3)\n        buffer.overwrite(4)\n\n        assertEquals(3, buffer.read())\n        assertEquals(4, buffer.read())\n        assertFailsWith<EmptyBufferException> {\n            buffer.read()\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/clock/.docs/instructions.md",
    "content": "# Instructions\n\nImplement a clock that handles times without dates.\n\nYou should be able to add and subtract minutes to it.\n\nTwo clocks that represent the same time should be equal to each other.\n"
  },
  {
    "path": "exercises/practice/clock/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Clock.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ClockCreationTest.kt\",\n      \"src/test/kotlin/ClockAddTest.kt\",\n      \"src/test/kotlin/ClockSubtractTest.kt\",\n      \"src/test/kotlin/ClockEqualTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Clock.kt\"\n    ]\n  },\n  \"blurb\": \"Implement a clock that handles times without dates.\",\n  \"source\": \"Pairing session with Erin Drummond\"\n}\n"
  },
  {
    "path": "exercises/practice/clock/.meta/src/reference/kotlin/Clock.kt",
    "content": "data class Clock(private var hours: Int, private var minutes: Int) {\n\n    companion object {\n        private const val MINUTES_IN_AN_HOUR = 60\n        private const val HOURS_IN_A_DAY = 24\n    }\n\n    init {\n        sanitiseTime()\n    }\n\n    override fun toString(): String {\n        return \"${hours.toTimeString()}:${minutes.toTimeString()}\"\n    }\n\n    fun add(minutes: Int) {\n        this.minutes += minutes\n        sanitiseTime()\n    }\n\n    fun subtract(minutes: Int) = add(minutes * -1)\n\n    private fun sanitiseTime() {\n        while (minutes < 0) {\n            minutes += MINUTES_IN_AN_HOUR\n            hours--\n        }\n\n        while (hours < 0) {\n            hours += HOURS_IN_A_DAY\n        }\n\n        val minutesOverflow = minutes / MINUTES_IN_AN_HOUR\n        minutes %= MINUTES_IN_AN_HOUR\n        hours = (hours + minutesOverflow) % HOURS_IN_A_DAY\n    }\n\n}\n\nprivate fun Int.toTimeString(): String {\n    return toString().padStart(length = 2, padChar = '0')\n}\n"
  },
  {
    "path": "exercises/practice/clock/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# on the hour\n\"a577bacc-106b-496e-9792-b3083ea8705e\" = true\n\n# past the hour\n\"b5d0c360-3b88-489b-8e84-68a1c7a4fa23\" = true\n\n# midnight is zero hours\n\"473223f4-65f3-46ff-a9f7-7663c7e59440\" = true\n\n# hour rolls over\n\"ca95d24a-5924-447d-9a96-b91c8334725c\" = true\n\n# hour rolls over continuously\n\"f3826de0-0925-4d69-8ac8-89aea7e52b78\" = true\n\n# sixty minutes is next hour\n\"a02f7edf-dfd4-4b11-b21a-86de3cc6a95c\" = true\n\n# minutes roll over\n\"8f520df6-b816-444d-b90f-8a477789beb5\" = true\n\n# minutes roll over continuously\n\"c75c091b-47ac-4655-8d40-643767fc4eed\" = true\n\n# hour and minutes roll over\n\"06343ecb-cf39-419d-a3f5-dcbae0cc4c57\" = true\n\n# hour and minutes roll over continuously\n\"be60810e-f5d9-4b58-9351-a9d1e90e660c\" = true\n\n# hour and minutes roll over to exactly midnight\n\"1689107b-0b5c-4bea-aad3-65ec9859368a\" = true\n\n# negative hour\n\"d3088ee8-91b7-4446-9e9d-5e2ad6219d91\" = true\n\n# negative hour rolls over\n\"77ef6921-f120-4d29-bade-80d54aa43b54\" = true\n\n# negative hour rolls over continuously\n\"359294b5-972f-4546-bb9a-a85559065234\" = true\n\n# negative minutes\n\"509db8b7-ac19-47cc-bd3a-a9d2f30b03c0\" = true\n\n# negative minutes roll over\n\"5d6bb225-130f-4084-84fd-9e0df8996f2a\" = true\n\n# negative minutes roll over continuously\n\"d483ceef-b520-4f0c-b94a-8d2d58cf0484\" = true\n\n# negative sixty minutes is previous hour\n\"1cd19447-19c6-44bf-9d04-9f8305ccb9ea\" = true\n\n# negative hour and minutes both roll over\n\"9d3053aa-4f47-4afc-bd45-d67a72cef4dc\" = true\n\n# negative hour and minutes both roll over continuously\n\"51d41fcf-491e-4ca0-9cae-2aa4f0163ad4\" = true\n\n# add minutes\n\"d098e723-ad29-4ef9-997a-2693c4c9d89a\" = true\n\n# add no minutes\n\"b6ec8f38-e53e-4b22-92a7-60dab1f485f4\" = true\n\n# add to next hour\n\"efd349dd-0785-453e-9ff8-d7452a8e7269\" = true\n\n# add more than one hour\n\"749890f7-aba9-4702-acce-87becf4ef9fe\" = true\n\n# add more than two hours with carry\n\"da63e4c1-1584-46e3-8d18-c9dc802c1713\" = true\n\n# add across midnight\n\"be167a32-3d33-4cec-a8bc-accd47ddbb71\" = true\n\n# add more than one day (1500 min = 25 hrs)\n\"6672541e-cdae-46e4-8be7-a820cc3be2a8\" = true\n\n# add more than two days\n\"1918050d-c79b-4cb7-b707-b607e2745c7e\" = true\n\n# subtract minutes\n\"37336cac-5ede-43a5-9026-d426cbe40354\" = true\n\n# subtract to previous hour\n\"0aafa4d0-3b5f-4b12-b3af-e3a9e09c047b\" = true\n\n# subtract more than an hour\n\"9b4e809c-612f-4b15-aae0-1df0acb801b9\" = true\n\n# subtract across midnight\n\"8b04bb6a-3d33-4e6c-8de9-f5de6d2c70d6\" = true\n\n# subtract more than two hours\n\"07c3bbf7-ce4d-4658-86e8-4a77b7a5ccd9\" = true\n\n# subtract more than two hours with borrow\n\"90ac8a1b-761c-4342-9c9c-cdc3ed5db097\" = true\n\n# subtract more than one day (1500 min = 25 hrs)\n\"2149f985-7136-44ad-9b29-ec023a97a2b7\" = true\n\n# subtract more than two days\n\"ba11dbf0-ac27-4acb-ada9-3b853ec08c97\" = true\n\n# clocks with same time\n\"f2fdad51-499f-4c9b-a791-b28c9282e311\" = true\n\n# clocks a minute apart\n\"5d409d4b-f862-4960-901e-ec430160b768\" = true\n\n# clocks an hour apart\n\"a6045fcf-2b52-4a47-8bb2-ef10a064cba5\" = true\n\n# clocks with hour overflow\n\"66b12758-0be5-448b-a13c-6a44bce83527\" = true\n\n# clocks with hour overflow by several days\n\"2b19960c-212e-4a71-9aac-c581592f8111\" = true\n\n# clocks with negative hour\n\"6f8c6541-afac-4a92-b0c2-b10d4e50269f\" = true\n\n# clocks with negative hour that wraps\n\"bb9d5a68-e324-4bf5-a75e-0e9b1f97a90d\" = true\n\n# clocks with negative hour that wraps multiple times\n\"56c0326d-565b-4d19-a26f-63b3205778b7\" = true\n\n# clocks with minute overflow\n\"c90b9de8-ddff-4ffe-9858-da44a40fdbc2\" = true\n\n# clocks with minute overflow by several days\n\"533a3dc5-59a7-491b-b728-a7a34fe325de\" = true\n\n# clocks with negative minute\n\"fff49e15-f7b7-4692-a204-0f6052d62636\" = true\n\n# clocks with negative minute that wraps\n\"605c65bb-21bd-43eb-8f04-878edf508366\" = true\n\n# clocks with negative minute that wraps multiple times\n\"b87e64ed-212a-4335-91fd-56da8421d077\" = true\n\n# clocks with negative hours and minutes\n\"822fbf26-1f3b-4b13-b9bf-c914816b53dd\" = true\n\n# clocks with negative hours and minutes that wrap\n\"e787bccd-cf58-4a1d-841c-ff80eaaccfaa\" = true\n\n# full clock and zeroed clock\n\"96969ca8-875a-48a1-86ae-257a528c44f5\" = true\n"
  },
  {
    "path": "exercises/practice/clock/.meta/version",
    "content": "2.4.0\n"
  },
  {
    "path": "exercises/practice/clock/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/clock/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/clock/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/clock/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/clock/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/clock/src/main/kotlin/Clock.kt",
    "content": "class Clock {\n    //TODO: implement proper constructor\n\n    //TODO: find a convenient way to take over `toString()` and `equals()`\n\n    fun subtract(minutes: Int) {\n        TODO(\"Implement the function to complete the task\")\n    }\n\n    fun add(minutes: Int) {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/clock/src/test/kotlin/ClockAddTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass ClockAddTest {\n\n    @Ignore\n    @Test\n    fun `add minutes`() =\n        Clock(10, 0)\n            .plusMinutes(3)\n            .shouldBe(\"10:03\")\n\n    @Ignore\n    @Test\n    fun `add no minutes`() =\n        Clock(6, 41)\n            .plusMinutes(0)\n            .shouldBe(\"06:41\")\n\n    @Ignore\n    @Test\n    fun `add to next hour`() =\n        Clock(0, 45)\n            .plusMinutes(40)\n            .shouldBe(\"01:25\")\n\n\n    @Ignore\n    @Test\n    fun `add more than one hour`() =\n        Clock(10, 0)\n            .plusMinutes(61)\n            .shouldBe(\"11:01\")\n\n\n    @Ignore\n    @Test\n    fun `add more than two hours with carry`() =\n        Clock(0, 45)\n            .plusMinutes(160)\n            .shouldBe(\"03:25\")\n\n\n    @Ignore\n    @Test\n    fun `add across midnight`() =\n        Clock(23, 59)\n            .plusMinutes(2)\n            .shouldBe(\"00:01\")\n\n\n    @Ignore\n    @Test\n    fun `add more than one day`() =\n        Clock(5, 32)\n            .plusMinutes(1500)\n            .shouldBe(\"06:32\")\n\n\n    @Ignore\n    @Test\n    fun `add more than two days`() =\n        Clock(1, 1)\n            .plusMinutes(3500)\n            .shouldBe(\"11:21\")\n\n}\n\nprivate fun Clock.plusMinutes(minutes: Int): Clock {\n    add(minutes)\n    return this\n}\n\nprivate fun Clock.shouldBe(expectation: String) = assertEquals(expectation, toString())\n"
  },
  {
    "path": "exercises/practice/clock/src/test/kotlin/ClockCreationTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass ClockCreationTest {\n\n    @Test\n    fun `on the hour`() = assertEquals(\"08:00\", Clock(8, 0).toString())\n\n    @Ignore\n    @Test\n    fun `past the hour`() = assertEquals(\"11:09\", Clock(11, 9).toString())\n\n    @Ignore\n    @Test\n    fun `midnight is zero hours`() = assertEquals(\"00:00\", Clock(24, 0).toString())\n\n    @Ignore\n    @Test\n    fun `hour rolls over`() = assertEquals(\"01:00\", Clock(25, 0).toString())\n\n    @Ignore\n    @Test\n    fun `hour rolls over continuously`() = assertEquals(\"04:00\", Clock(100, 0).toString())\n\n    @Ignore\n    @Test\n    fun `sixty minutes is next hour`() = assertEquals(\"02:00\", Clock(1, 60).toString())\n\n    @Ignore\n    @Test\n    fun `minutes roll over`() = assertEquals(\"02:40\", Clock(0, 160).toString())\n\n    @Ignore\n    @Test\n    fun `minutes roll over continuously`() = assertEquals(\"04:43\", Clock(0, 1723).toString())\n\n    @Ignore\n    @Test\n    fun `hour and minutes roll over`() = assertEquals(\"03:40\", Clock(25, 160).toString())\n\n    @Ignore\n    @Test\n    fun `hour and minutes roll over continuously`() = assertEquals(\"11:01\", Clock(201, 3001).toString())\n\n    @Ignore\n    @Test\n    fun `hour and minutes roll over to exactly midnight`() = assertEquals(\"00:00\", Clock(72, 8640).toString())\n\n    @Ignore\n    @Test\n    fun `negative hour`() = assertEquals(\"23:15\", Clock(-1, 15).toString())\n\n    @Ignore\n    @Test\n    fun `negative hour rolls over`() = assertEquals(\"23:00\", Clock(-25, 0).toString())\n\n    @Ignore\n    @Test\n    fun `negative hour rolls over continuously`() = assertEquals(\"05:00\", Clock(-91, 0).toString())\n\n    @Ignore\n    @Test\n    fun `negative minutes`() = assertEquals(\"00:20\", Clock(1, -40).toString())\n\n    @Ignore\n    @Test\n    fun `negative minutes roll over`() = assertEquals(\"22:20\", Clock(1, -160).toString())\n\n    @Ignore\n    @Test\n    fun `negative minutes roll over continuously`() = assertEquals(\"16:40\", Clock(1, -4820).toString())\n\n    @Ignore\n    @Test\n    fun `negative sixty minutes is previous hour`() = assertEquals(\"01:00\", Clock(2, -60).toString())\n\n    @Ignore\n    @Test\n    fun `negative hour and minutes both roll over`() = assertEquals(\"20:20\", Clock(-25, -160).toString())\n\n    @Ignore\n    @Test\n    fun `negative hour and minutes both roll over continuously`() =\n        assertEquals(\"22:10\", Clock(-121, -5810).toString())\n\n}\n"
  },
  {
    "path": "exercises/practice/clock/src/test/kotlin/ClockEqualTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertNotEquals\nimport kotlin.test.assertEquals\n\nclass ClockEqualTest {\n\n    @Ignore\n    @Test\n    fun `same time`() = assertEquals(Clock(15, 37), Clock(15, 37))\n\n    @Ignore\n    @Test\n    fun `clocks a minute apart`() = assertNotEquals(Clock(15, 36), Clock(15, 37))\n\n    @Ignore\n    @Test\n    fun `clocks an hour apart`() = assertNotEquals(Clock(14, 37), Clock(15, 37))\n\n    @Ignore\n    @Test\n    fun `hour overflow`() = assertEquals(Clock(10, 37), Clock(34, 37))\n\n    @Ignore\n    @Test\n    fun `hour overflow by several days`() = assertEquals(Clock(3, 11), Clock(99, 11))\n\n    @Ignore\n    @Test\n    fun `negative hour`() = assertEquals(Clock(22, 40), Clock(-2, 40))\n\n    @Ignore\n    @Test\n    fun `negative hour that wraps`() = assertEquals(Clock(17, 3), Clock(-31, 3))\n\n    @Ignore\n    @Test\n    fun `negative hour that wraps multiple times`() = assertEquals(Clock(13, 49), Clock(-83, 49))\n\n    @Ignore\n    @Test\n    fun `minute overflow`() = assertEquals(Clock(0, 1), Clock(0, 1441))\n\n    @Ignore\n    @Test\n    fun `minute overflow by several days`() = assertEquals(Clock(2, 2), Clock(2, 4322))\n\n    @Ignore\n    @Test\n    fun `negative minute`() = assertEquals(Clock(2, 40), Clock(3, -20))\n\n    @Ignore\n    @Test\n    fun `negative minute that wraps`() = assertEquals(Clock(4, 10), Clock(5, -1490))\n\n    @Ignore\n    @Test\n    fun `negative minute that wraps multiple times`() = assertEquals(Clock(6, 15), Clock(6, -4305))\n\n    @Ignore\n    @Test\n    fun `negative hours and minutes`() = assertEquals(Clock(7, 32), Clock(-12, -268))\n\n    @Ignore\n    @Test\n    fun `negative hours and minutes that wrap`() = assertEquals(Clock(18, 7), Clock(-54, -11513))\n\n    @Ignore\n    @Test\n    fun `full clock and zeroed clock`() = assertEquals(Clock(24, 0), Clock(0, 0))\n\n}\n"
  },
  {
    "path": "exercises/practice/clock/src/test/kotlin/ClockSubtractTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass ClockSubtractTest {\n\n    @Ignore\n    @Test\n    fun `subtract minutes`() =\n        Clock(10, 3)\n            .minusMinutes(3)\n            .shouldBe(\"10:00\")\n\n    @Ignore\n    @Test\n    fun `subtract to previous hour`() =\n        Clock(10, 3)\n            .minusMinutes(30)\n            .shouldBe(\"09:33\")\n\n    @Ignore\n    @Test\n    fun `subtract more than an hour`() =\n        Clock(10, 3)\n            .minusMinutes(70)\n            .shouldBe(\"08:53\")\n\n    @Ignore\n    @Test\n    fun `subtract across midnight`() =\n        Clock(0, 3)\n            .minusMinutes(4)\n            .shouldBe(\"23:59\")\n\n    @Ignore\n    @Test\n    fun `subtract more than two hours`() =\n        Clock(0, 0)\n            .minusMinutes(160)\n            .shouldBe(\"21:20\")\n\n    @Ignore\n    @Test\n    fun `subtract more than two hours with borrow`() =\n        Clock(6, 15)\n            .minusMinutes(160)\n            .shouldBe(\"03:35\")\n\n    @Ignore\n    @Test\n    fun `subtract more than one day`() =\n        Clock(5, 32)\n            .minusMinutes(1500)\n            .shouldBe(\"04:32\")\n\n    @Ignore\n    @Test\n    fun `subtract more than two days`() =\n        Clock(2, 20)\n            .minusMinutes(3000)\n            .shouldBe(\"00:20\")\n\n}\n\nprivate fun Clock.minusMinutes(minutes: Int): Clock {\n    subtract(minutes)\n    return this\n}\n\nprivate fun Clock.shouldBe(expectation: String) = assertEquals(expectation, toString())\n"
  },
  {
    "path": "exercises/practice/collatz-conjecture/.docs/instructions.md",
    "content": "# Instructions\n\nGiven a positive integer, return the number of steps it takes to reach 1 according to the rules of the Collatz Conjecture.\n"
  },
  {
    "path": "exercises/practice/collatz-conjecture/.docs/introduction.md",
    "content": "# Introduction\n\nOne evening, you stumbled upon an old notebook filled with cryptic scribbles, as though someone had been obsessively chasing an idea.\nOn one page, a single question stood out: **Can every number find its way to 1?**\nIt was tied to something called the **Collatz Conjecture**, a puzzle that has baffled thinkers for decades.\n\nThe rules were deceptively simple.\nPick any positive integer.\n\n- If it's even, divide it by 2.\n- If it's odd, multiply it by 3 and add 1.\n\nThen, repeat these steps with the result, continuing indefinitely.\n\nCurious, you picked number 12 to test and began the journey:\n\n12 ➜ 6 ➜ 3 ➜ 10 ➜ 5 ➜ 16 ➜ 8 ➜ 4 ➜ 2 ➜ 1\n\nCounting from the second number (6), it took 9 steps to reach 1, and each time the rules repeated, the number kept changing.\nAt first, the sequence seemed unpredictable — jumping up, down, and all over.\nYet, the conjecture claims that no matter the starting number, we'll always end at 1.\n\nIt was fascinating, but also puzzling.\nWhy does this always seem to work?\nCould there be a number where the process breaks down, looping forever or escaping into infinity?\nThe notebook suggested solving this could reveal something profound — and with it, fame, [fortune][collatz-prize], and a place in history awaits whoever could unlock its secrets.\n\n[collatz-prize]: https://mathprize.net/posts/collatz-conjecture/\n"
  },
  {
    "path": "exercises/practice/collatz-conjecture/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/CollatzCalculator.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/CollatzCalculatorTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/CollatzCalculator.kt\"\n    ]\n  },\n  \"blurb\": \"Calculate the number of steps to reach 1 using the Collatz conjecture.\",\n  \"source\": \"Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Collatz_conjecture\"\n}\n"
  },
  {
    "path": "exercises/practice/collatz-conjecture/.meta/src/reference/kotlin/CollatzCalculator.kt",
    "content": "object CollatzCalculator {\n\n    fun computeStepCount(start: Int): Int {\n        require(start > 0) { \"Only natural numbers are allowed\" }\n\n        if (start == 1) return 0\n\n        val next = if (start % 2 == 0) start / 2 else 3 * start + 1\n        return 1 + computeStepCount(next)\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/collatz-conjecture/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# zero steps for one\n\"540a3d51-e7a6-47a5-92a3-4ad1838f0bfd\" = true\n\n# divide if even\n\"3d76a0a6-ea84-444a-821a-f7857c2c1859\" = true\n\n# even and odd steps\n\"754dea81-123c-429e-b8bc-db20b05a87b9\" = true\n\n# large number of even and odd steps\n\"ecfd0210-6f85-44f6-8280-f65534892ff6\" = true\n\n# zero is an error\n\"7d4750e6-def9-4b86-aec7-9f7eb44f95a3\" = true\n\n# negative value is an error\n\"c6c795bf-a288-45e9-86a1-841359ad426d\" = true\n"
  },
  {
    "path": "exercises/practice/collatz-conjecture/.meta/version",
    "content": "1.2.1\n"
  },
  {
    "path": "exercises/practice/collatz-conjecture/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/collatz-conjecture/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/collatz-conjecture/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/collatz-conjecture/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/collatz-conjecture/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/collatz-conjecture/src/main/kotlin/CollatzCalculator.kt",
    "content": "object CollatzCalculator {\n    fun computeStepCount(start: Int): Int {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/collatz-conjecture/src/test/kotlin/CollatzCalculatorTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.rules.ExpectedException\nimport kotlin.test.assertEquals\n\nclass CollatzCalculatorTest {\n\n    @Rule\n    @JvmField\n    var expectedException: ExpectedException = ExpectedException.none()\n\n    @Test\n    fun `zero steps for 1`() = assertStepsEqual(1, 0)\n\n    @Ignore\n    @Test\n    fun `divide if even`() = assertStepsEqual(16, 4)\n\n    @Ignore\n    @Test\n    fun `even and odd steps`() = assertStepsEqual(12, 9)\n\n    @Ignore\n    @Test\n    fun `large number of even and odd steps`() = assertStepsEqual(1000000, 152)\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid input - zero`() {\n        steps(0)\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid input - negative`() {\n        steps(-15)\n    }\n\n}\n\nprivate fun assertStepsEqual(input: Int, steps: Int) = assertEquals(steps, steps(input))\n\nprivate fun steps(input: Int) = CollatzCalculator.computeStepCount(input)\n"
  },
  {
    "path": "exercises/practice/complex-numbers/.docs/instructions.md",
    "content": "# Instructions\n\nA **complex number** is expressed in the form `z = a + b * i`, where:\n\n- `a` is the **real part** (a real number),\n\n- `b` is the **imaginary part** (also a real number), and\n\n- `i` is the **imaginary unit** satisfying `i^2 = -1`.\n\n## Operations on Complex Numbers\n\n### Conjugate\n\nThe conjugate of the complex number `z = a + b * i` is given by:\n\n```text\nzc = a - b * i\n```\n\n### Absolute Value\n\nThe absolute value (or modulus) of `z` is defined as:\n\n```text\n|z| = sqrt(a^2 + b^2)\n```\n\nThe square of the absolute value is computed as the product of `z` and its conjugate `zc`:\n\n```text\n|z|^2 = z * zc = a^2 + b^2\n```\n\n### Addition\n\nThe sum of two complex numbers `z1 = a + b * i` and `z2 = c + d * i` is computed by adding their real and imaginary parts separately:\n\n```text\nz1 + z2 = (a + b * i) + (c + d * i)\n        = (a + c) + (b + d) * i\n```\n\n### Subtraction\n\nThe difference of two complex numbers is obtained by subtracting their respective parts:\n\n```text\nz1 - z2 = (a + b * i) - (c + d * i)\n        = (a - c) + (b - d) * i\n```\n\n### Multiplication\n\nThe product of two complex numbers is defined as:\n\n```text\nz1 * z2 = (a + b * i) * (c + d * i)\n        = (a * c - b * d) + (b * c + a * d) * i\n```\n\n### Reciprocal\n\nThe reciprocal of a non-zero complex number is given by:\n\n```text\n1 / z = 1 / (a + b * i)\n      = a / (a^2 + b^2) - b / (a^2 + b^2) * i\n```\n\n### Division\n\nThe division of one complex number by another is given by:\n\n```text\nz1 / z2 = z1 * (1 / z2)\n        = (a + b * i) / (c + d * i)\n        = (a * c + b * d) / (c^2 + d^2) + (b * c - a * d) / (c^2 + d^2) * i\n```\n\n### Exponentiation\n\nRaising _e_ (the base of the natural logarithm) to a complex exponent can be expressed using Euler's formula:\n\n```text\ne^(a + b * i) = e^a * e^(b * i)\n              = e^a * (cos(b) + i * sin(b))\n```\n\n## Implementation Requirements\n\nGiven that you should not use built-in support for complex numbers, implement the following operations:\n\n- **addition** of two complex numbers\n- **subtraction** of two complex numbers\n- **multiplication** of two complex numbers\n- **division** of two complex numbers\n- **conjugate** of a complex number\n- **absolute value** of a complex number\n- **exponentiation** of _e_ (the base of the natural logarithm) to a complex number\n"
  },
  {
    "path": "exercises/practice/complex-numbers/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"DanCorder\",\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/ComplexNumber.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ComplexNumberTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/ComplexNumber.kt\"\n    ]\n  },\n  \"blurb\": \"Implement complex numbers.\",\n  \"source\": \"Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Complex_number\"\n}\n"
  },
  {
    "path": "exercises/practice/complex-numbers/.meta/src/reference/kotlin/ComplexNumber.kt",
    "content": "import kotlin.math.*\n\ndata class ComplexNumber(val real: Double = 0.0, val imag: Double = 0.0) {\n\n    val abs = hypot(real, imag)\n\n    operator fun plus(other: ComplexNumber)\n            = copy(real = real + other.real, imag = imag + other.imag)\n\n    operator fun minus(other: ComplexNumber)\n            = copy(real = real - other.real, imag = imag - other.imag)\n\n    operator fun times(other: ComplexNumber)\n            = copy(real = real*other.real - imag*other.imag, imag = real*other.imag + imag*other.real)\n\n    operator fun div(other: ComplexNumber)\n            = this * other.conjugate() / other.abs.pow(2.0)\n\n    operator fun times(factor: Double)\n            = copy(real = factor * real, imag = factor * imag)\n\n    operator fun div(factor: Double)\n            = copy(real = real / factor, imag = imag / factor)\n\n    fun conjugate() = copy(imag = -1 * imag)\n\n}\n\nfun exponential(exponent: ComplexNumber)\n        = ComplexNumber(real = cos(exponent.imag), imag = sin(exponent.imag)) * exp(exponent.real)\n"
  },
  {
    "path": "exercises/practice/complex-numbers/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# Real part of a purely real number\n\"9f98e133-eb7f-45b0-9676-cce001cd6f7a\" = true\n\n# Real part of a purely imaginary number\n\"07988e20-f287-4bb7-90cf-b32c4bffe0f3\" = true\n\n# Real part of a number with real and imaginary part\n\"4a370e86-939e-43de-a895-a00ca32da60a\" = true\n\n# Imaginary part of a purely real number\n\"9b3fddef-4c12-4a99-b8f8-e3a42c7ccef6\" = true\n\n# Imaginary part of a purely imaginary number\n\"a8dafedd-535a-4ed3-8a39-fda103a2b01e\" = true\n\n# Imaginary part of a number with real and imaginary part\n\"0f998f19-69ee-4c64-80ef-01b086feab80\" = true\n\n# Imaginary unit\n\"a39b7fd6-6527-492f-8c34-609d2c913879\" = true\n\n# Add purely real numbers\n\"9a2c8de9-f068-4f6f-b41c-82232cc6c33e\" = true\n\n# Add purely imaginary numbers\n\"657c55e1-b14b-4ba7-bd5c-19db22b7d659\" = true\n\n# Add numbers with real and imaginary part\n\"4e1395f5-572b-4ce8-bfa9-9a63056888da\" = true\n\n# Subtract purely real numbers\n\"1155dc45-e4f7-44b8-af34-a91aa431475d\" = true\n\n# Subtract purely imaginary numbers\n\"f95e9da8-acd5-4da4-ac7c-c861b02f774b\" = true\n\n# Subtract numbers with real and imaginary part\n\"f876feb1-f9d1-4d34-b067-b599a8746400\" = true\n\n# Multiply purely real numbers\n\"8a0366c0-9e16-431f-9fd7-40ac46ff4ec4\" = true\n\n# Multiply purely imaginary numbers\n\"e560ed2b-0b80-4b4f-90f2-63cefc911aaf\" = true\n\n# Multiply numbers with real and imaginary part\n\"4d1d10f0-f8d4-48a0-b1d0-f284ada567e6\" = true\n\n# Divide purely real numbers\n\"b0571ddb-9045-412b-9c15-cd1d816d36c1\" = true\n\n# Divide purely imaginary numbers\n\"5bb4c7e4-9934-4237-93cc-5780764fdbdd\" = true\n\n# Divide numbers with real and imaginary part\n\"c4e7fef5-64ac-4537-91c2-c6529707701f\" = true\n\n# Absolute value of a positive purely real number\n\"c56a7332-aad2-4437-83a0-b3580ecee843\" = true\n\n# Absolute value of a negative purely real number\n\"cf88d7d3-ee74-4f4e-8a88-a1b0090ecb0c\" = true\n\n# Absolute value of a purely imaginary number with positive imaginary part\n\"bbe26568-86c1-4bb4-ba7a-da5697e2b994\" = true\n\n# Absolute value of a purely imaginary number with negative imaginary part\n\"3b48233d-468e-4276-9f59-70f4ca1f26f3\" = true\n\n# Absolute value of a number with real and imaginary part\n\"fe400a9f-aa22-4b49-af92-51e0f5a2a6d3\" = true\n\n# Conjugate a purely real number\n\"fb2d0792-e55a-4484-9443-df1eddfc84a2\" = true\n\n# Conjugate a purely imaginary number\n\"e37fe7ac-a968-4694-a460-66cb605f8691\" = true\n\n# Conjugate a number with real and imaginary part\n\"f7704498-d0be-4192-aaf5-a1f3a7f43e68\" = true\n\n# Euler's identity/formula\n\"6d96d4c6-2edb-445b-94a2-7de6d4caaf60\" = true\n\n# Exponential of 0\n\"2d2c05a0-4038-4427-a24d-72f6624aa45f\" = true\n\n# Exponential of a purely real number\n\"ed87f1bd-b187-45d6-8ece-7e331232c809\" = true\n\n# Exponential of a number with real and imaginary part\n\"08eedacc-5a95-44fc-8789-1547b27a8702\" = true\n"
  },
  {
    "path": "exercises/practice/complex-numbers/.meta/version",
    "content": "1.3.0\n"
  },
  {
    "path": "exercises/practice/complex-numbers/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/complex-numbers/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/complex-numbers/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/complex-numbers/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/complex-numbers/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/complex-numbers/src/main/kotlin/ComplexNumber.kt",
    "content": "data class ComplexNumber(val real: Double = 0.0, val imag: Double = 0.0)\n"
  },
  {
    "path": "exercises/practice/complex-numbers/src/test/kotlin/ComplexNumberTest.kt",
    "content": "import org.junit.Assert.assertEquals\nimport org.junit.Ignore\nimport org.junit.Test\nimport kotlin.math.*\n\nclass ComplexNumberTest {\n\n    // Test helpers\n\n    companion object {\n        private const val DOUBLE_EQUALITY_TOLERANCE = 1e-15\n    }\n\n    private fun assertDoublesEqual(d1: Double, d2: Double) {\n        assertEquals(d1, d2, DOUBLE_EQUALITY_TOLERANCE)\n    }\n\n    private fun assertComplexNumbersEqual(c1: ComplexNumber, c2: ComplexNumber) {\n        assertDoublesEqual(c1.real, c2.real)\n        assertDoublesEqual(c1.imag, c2.imag)\n    }\n\n    // Tests\n\n    @Test\n    fun testImaginaryUnitExhibitsDefiningProperty() {\n        val expected = ComplexNumber(real = -1.0)\n        val actual = ComplexNumber(imag = 1.0) * ComplexNumber(imag = 1.0)\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testAdditionWithPurelyRealNumbers() {\n        val expected = ComplexNumber(real = 3.0)\n        val actual = ComplexNumber(real = 1.0) + ComplexNumber(real = 2.0)\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testAdditionWithPurelyImaginaryNumbers() {\n        val expected = ComplexNumber(imag = 3.0)\n        val actual = ComplexNumber(imag = 1.0) + ComplexNumber(imag = 2.0)\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testAdditionWithRealAndImaginaryParts() {\n        val expected = ComplexNumber(real = 4.0, imag = 6.0)\n        val actual = ComplexNumber(real = 1.0, imag = 2.0) + ComplexNumber(real = 3.0, imag = 4.0)\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testSubtractionWithPurelyRealNumbers() {\n        val expected = ComplexNumber(real = -1.0, imag = 0.0)\n        val actual = ComplexNumber(real = 1.0, imag = 0.0) - ComplexNumber(real = 2.0, imag = 0.0)\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testSubtractionWithPurelyImaginaryNumbers() {\n        val expected = ComplexNumber(imag = -1.0)\n        val actual = ComplexNumber(imag = 1.0) - ComplexNumber(imag = 2.0)\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testSubtractionWithRealAndImaginaryParts() {\n        val expected = ComplexNumber(real = -2.0, imag = -2.0)\n        val actual = ComplexNumber(real = 1.0, imag = 2.0) - ComplexNumber(real = 3.0, imag = 4.0)\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testMultiplicationWithPurelyRealNumbers() {\n        val expected = ComplexNumber(real = 2.0)\n        val actual = ComplexNumber(real = 1.0) * ComplexNumber(real = 2.0)\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testMultiplicationWithPurelyImaginaryNumbers() {\n        val expected = ComplexNumber(real = -2.0)\n        val actual = ComplexNumber(imag = 1.0) * ComplexNumber(imag = 2.0)\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testMultiplicationWithRealAndImaginaryParts() {\n        val expected = ComplexNumber(real = -5.0, imag = 10.0)\n        val actual = ComplexNumber(real = 1.0, imag = 2.0) * ComplexNumber(real = 3.0, imag = 4.0)\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testDivisionWithPurelyRealNumbers() {\n        val expected = ComplexNumber(real = 0.5)\n        val actual = ComplexNumber(real = 1.0) / ComplexNumber(real = 2.0)\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testDivisionWithPurelyImaginaryNumbers() {\n        val expected = ComplexNumber(real = 0.5)\n        val actual = ComplexNumber(imag = 1.0) / ComplexNumber(imag = 2.0)\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testDivisionWithRealAndImaginaryParts() {\n        val expected = ComplexNumber(real = 0.44, imag = 0.08)\n        val actual = ComplexNumber(real = 1.0, imag = 2.0) / ComplexNumber(real = 3.0, imag = 4.0)\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testAbsoluteValueOfPositivePurelyRealNumber() {\n        val expected = 5.0\n        val actual = ComplexNumber(real = 5.0).abs\n        assertDoublesEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testAbsoluteValueOfNegativePurelyRealNumber() {\n        val expected = 5.0\n        val actual = ComplexNumber(real = -5.0).abs\n        assertDoublesEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testAbsoluteValueOfPurelyImaginaryNumberWithPositiveImaginaryPart() {\n        val expected = 5.0\n        val actual = ComplexNumber(imag = 5.0).abs\n        assertDoublesEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testAbsoluteValueOfPurelyImaginaryNumberWithNegativeImaginaryPart() {\n        val expected = 5.0\n        val actual = ComplexNumber(imag = -5.0).abs\n        assertDoublesEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testAbsoluteValueOfNumberWithRealAndImaginaryParts() {\n        val expected = 5.0\n        val actual = ComplexNumber(real = 3.0, imag = 4.0).abs\n        assertDoublesEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testConjugationOfPurelyRealNumber() {\n        val expected = ComplexNumber(real = 5.0)\n        val actual = ComplexNumber(real = 5.0).conjugate()\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testConjugationOfPurelyImaginaryNumber() {\n        val expected = ComplexNumber(imag = -5.0)\n        val actual = ComplexNumber(imag = 5.0).conjugate()\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testConjugationOfNumberWithRealAndImaginaryParts() {\n        val expected = ComplexNumber(real = 1.0, imag = -1.0)\n        val actual = ComplexNumber(real = 1.0, imag = 1.0).conjugate()\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testRealPartOfPurelyRealNumber() {\n        val expected = 1.0\n        val actual = ComplexNumber(real = 1.0).real\n        assertDoublesEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testRealPartOfPurelyImaginaryNumber() {\n        val expected = 0.0\n        val actual = ComplexNumber(imag = 1.0).real\n        assertDoublesEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testRealPartOfNumberWithRealAndImaginaryParts() {\n        val expected = 1.0\n        val actual = ComplexNumber(real = 1.0, imag = 2.0).real\n        assertDoublesEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testImaginaryPartOfPurelyRealNumber() {\n        val expected = 0.0\n        val actual = ComplexNumber(real = 1.0).imag\n        assertDoublesEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testImaginaryPartOfPurelyImaginaryNumber() {\n        val expected = 1.0\n        val actual = ComplexNumber(imag = 1.0).imag\n        assertDoublesEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testImaginaryPartOfNumberWithRealAndImaginaryParts() {\n        val expected = 2.0\n        val actual = ComplexNumber(real = 1.0, imag = 2.0).imag\n        assertDoublesEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testExponentialOfPurelyImaginaryNumber() {\n        val expected = ComplexNumber(real = -1.0)\n        val actual = exponential(ComplexNumber(imag = PI))\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testExponentialOfZero() {\n        val expected = ComplexNumber(real = 1.0)\n        val actual = exponential(ComplexNumber())\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testExponentialOfPurelyRealNumber() {\n        val expected = ComplexNumber(real = E)\n        val actual = exponential(ComplexNumber(real = 1.0))\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n    @Ignore\n    @Test\n    fun testExponentialOfANumberWithRealAndImaginaryPart() {\n        val expected = ComplexNumber(real = -2.0)\n        val actual = exponential(ComplexNumber(real = ln(2.0), imag = PI))\n        assertComplexNumbersEqual(expected, actual)\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/crypto-square/.docs/instructions.md",
    "content": "# Instructions\n\nImplement the classic method for composing secret messages called a square code.\n\nGiven an English text, output the encoded version of that text.\n\nFirst, the input is normalized: the spaces and punctuation are removed from the English text and the message is down-cased.\n\nThen, the normalized characters are broken into rows.\nThese rows can be regarded as forming a rectangle when printed with intervening newlines.\n\nFor example, the sentence\n\n```text\n\"If man was meant to stay on the ground, god would have given us roots.\"\n```\n\nis normalized to:\n\n```text\n\"ifmanwasmeanttostayonthegroundgodwouldhavegivenusroots\"\n```\n\nThe plaintext should be organized into a rectangle as square as possible.\nThe size of the rectangle should be decided by the length of the message.\n\nIf `c` is the number of columns and `r` is the number of rows, then for the rectangle `r` x `c` find the smallest possible integer `c` such that:\n\n- `r * c >= length of message`,\n- and `c >= r`,\n- and `c - r <= 1`.\n\nOur normalized text is 54 characters long, dictating a rectangle with `c = 8` and `r = 7`:\n\n```text\n\"ifmanwas\"\n\"meanttos\"\n\"tayonthe\"\n\"groundgo\"\n\"dwouldha\"\n\"vegivenu\"\n\"sroots  \"\n```\n\nThe coded message is obtained by reading down the columns going left to right.\n\nThe message above is coded as:\n\n```text\n\"imtgdvsfearwermayoogoanouuiontnnlvtwttddesaohghnsseoau\"\n```\n\nOutput the encoded text in chunks that fill perfect rectangles `(r X c)`, with `c` chunks of `r` length, separated by spaces.\nFor phrases that are `n` characters short of the perfect rectangle, pad each of the last `n` chunks with a single trailing space.\n\n```text\n\"imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn  sseoau \"\n```\n\nNotice that were we to stack these, we could visually decode the ciphertext back in to the original message:\n\n```text\n\"imtgdvs\"\n\"fearwer\"\n\"mayoogo\"\n\"anouuio\"\n\"ntnnlvt\"\n\"wttddes\"\n\"aohghn \"\n\"sseoau \"\n```\n"
  },
  {
    "path": "exercises/practice/crypto-square/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/CryptoSquare.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/CryptoSquareTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/CryptoSquare.kt\"\n    ]\n  },\n  \"blurb\": \"Implement the classic method for composing secret messages called a square code.\",\n  \"source\": \"J Dalbey's Programming Practice problems\",\n  \"source_url\": \"https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html\"\n}\n"
  },
  {
    "path": "exercises/practice/crypto-square/.meta/src/reference/kotlin/CryptoSquare.kt",
    "content": "import kotlin.math.sqrt\n\nobject CryptoSquare {\n\n    fun ciphertext(plaintext: String): String {\n        val sanitized = plaintext.filter { it.isLetterOrDigit() }.lowercase()\n        if (sanitized.isEmpty()) {\n            return \"\"\n        }\n\n        val (cols, rows) = calcSquare(sanitized.length)\n\n        return (0 until cols * rows)\n                .map { i -> (i % rows) * cols + (i / rows) }\n                .map { cursor -> if (cursor < sanitized.length) sanitized[cursor] else ' ' }\n                .joinToString(\"\")\n                .chunked(rows)\n                .joinToString(\" \")\n    }\n\n    private fun calcSquare(size: Int): Pair<Int, Int> {\n        val sq = sqrt(size.toDouble()).toInt()\n        return when {\n            sq * sq >= size -> Pair(sq, sq) // 9 => 3 * 3\n            (sq + 1) * sq >= size -> Pair(sq + 1, sq) // 54 => 8 * 7\n            else -> Pair(sq + 1, sq + 1) // 8 => 3 * 3\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/crypto-square/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# empty plaintext results in an empty ciphertext\n\"407c3837-9aa7-4111-ab63-ec54b58e8e9f\" = true\n\n# Lowercase\n\"64131d65-6fd9-4f58-bdd8-4a2370fb481d\" = true\n\n# Remove spaces\n\"63a4b0ed-1e3c-41ea-a999-f6f26ba447d6\" = true\n\n# Remove punctuation\n\"1b5348a1-7893-44c1-8197-42d48d18756c\" = true\n\n# 9 character plaintext results in 3 chunks of 3 characters\n\"8574a1d3-4a08-4cec-a7c7-de93a164f41a\" = true\n\n# 8 character plaintext results in 3 chunks, the last one with a trailing space\n\"a65d3fa1-9e09-43f9-bcec-7a672aec3eae\" = true\n\n# 54 character plaintext results in 7 chunks, the last two with trailing spaces\n\"fbcb0c6d-4c39-4a31-83f6-c473baa6af80\" = true\n"
  },
  {
    "path": "exercises/practice/crypto-square/.meta/version",
    "content": "3.2.0\n"
  },
  {
    "path": "exercises/practice/crypto-square/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/crypto-square/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/crypto-square/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/crypto-square/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/crypto-square/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/crypto-square/src/main/kotlin/CryptoSquare.kt",
    "content": "object CryptoSquare {\n\n    fun ciphertext(plaintext: String): String {\n        TODO(\"Implement the function to complete the task\")\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/crypto-square/src/test/kotlin/CryptoSquareTest.kt",
    "content": "import kotlin.test.Ignore\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\n\nclass CryptoSquareTest {\n\n    @Test\n    fun `empty plaintext results in empty ciphertext`() {\n        val plaintext = \"\"\n        val expectedOutput = \"\"\n        assertEquals(expectedOutput, CryptoSquare.ciphertext(plaintext))\n    }\n\n    @Ignore\n    @Test\n    fun `letters are lower cased during encryption`() {\n        val plaintext = \"A\"\n        val expectedOutput = \"a\"\n        assertEquals(expectedOutput, CryptoSquare.ciphertext(plaintext))\n    }\n\n    @Ignore\n    @Test\n    fun `spaces are removed during encryption`() {\n        val plaintext = \" b \"\n        val expectedOutput = \"b\"\n        assertEquals(expectedOutput, CryptoSquare.ciphertext(plaintext))\n    }\n\n    @Ignore\n    @Test\n    fun `punctuation is removed during encryption`() {\n        val plaintext = \"@1,%!\"\n        val expectedOutput = \"1\"\n        assertEquals(expectedOutput, CryptoSquare.ciphertext(plaintext))\n    }\n\n    @Ignore\n    @Test\n    fun `nine character plaintext results in three chunks of three characters`() {\n        val plaintext = \"This is fun!\"\n        val expectedOutput = \"tsf hiu isn\"\n        assertEquals(expectedOutput, CryptoSquare.ciphertext(plaintext))\n    }\n\n    @Ignore\n    @Test\n    fun `eight character plaintext results in three chunks with a trailing space`() {\n        val plaintext = \"Chill out.\"\n        val expectedOutput = \"clu hlt io \"\n        assertEquals(expectedOutput, CryptoSquare.ciphertext(plaintext))\n    }\n\n    @Ignore\n    @Test\n    fun `fifty four character plaintext results in seven chunks with trailing spaces`() {\n        val plaintext = \"If man was meant to stay on the ground, god would have given us roots.\"\n        val expectedOutput = \"imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn  sseoau \"\n        assertEquals(expectedOutput, CryptoSquare.ciphertext(plaintext))\n    }\n}\n"
  },
  {
    "path": "exercises/practice/custom-set/.docs/instructions.md",
    "content": "# Instructions\n\nCreate a custom set type.\n\nSometimes it is necessary to define a custom data structure of some type, like a set.\nIn this exercise you will define your own set.\nHow it works internally doesn't matter, as long as it behaves like a set of unique elements.\n"
  },
  {
    "path": "exercises/practice/custom-set/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/CustomSet.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/CustomSetTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/CustomSet.kt\"\n    ]\n  },\n  \"blurb\": \"Create a custom set type.\"\n}\n"
  },
  {
    "path": "exercises/practice/custom-set/.meta/src/reference/kotlin/CustomSet.kt",
    "content": "class CustomSet(vararg elements: Int) {\n\n    private val set: MutableSet<Int> = elements.toMutableSet()\n\n    fun isEmpty(): Boolean = set.isEmpty()\n\n    fun isSubset(other: CustomSet): Boolean = other.set.containsAll(set)\n\n    fun isDisjoint(other: CustomSet): Boolean = set.intersect(other.set).isEmpty()\n\n    fun contains(other: Int): Boolean = set.contains(other)\n\n    fun intersection(other: CustomSet): CustomSet = apply { set.retainAll(other.set) }\n\n    fun add(other: Int) = set.add(other)\n\n    override fun equals(other: Any?): Boolean = (other != null && other is CustomSet && set == other.set)\n\n    operator fun plus(other: CustomSet): CustomSet = apply { set.addAll(other.set) }\n\n    operator fun minus(other: CustomSet): CustomSet = apply { set.removeAll(other.set) }\n\n}\n"
  },
  {
    "path": "exercises/practice/custom-set/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# sets with no elements are empty\n\"20c5f855-f83a-44a7-abdd-fe75c6cf022b\" = true\n\n# sets with elements are not empty\n\"d506485d-5706-40db-b7d8-5ceb5acf88d2\" = true\n\n# nothing is contained in an empty set\n\"759b9740-3417-44c3-8ca3-262b3c281043\" = true\n\n# when the element is in the set\n\"f83cd2d1-2a85-41bc-b6be-80adbff4be49\" = true\n\n# when the element is not in the set\n\"93423fc0-44d0-4bc0-a2ac-376de8d7af34\" = true\n\n# empty set is a subset of another empty set\n\"c392923a-637b-4495-b28e-34742cd6157a\" = true\n\n# empty set is a subset of non-empty set\n\"5635b113-be8c-4c6f-b9a9-23c485193917\" = true\n\n# non-empty set is not a subset of empty set\n\"832eda58-6d6e-44e2-92c2-be8cf0173cee\" = true\n\n# set is a subset of set with exact same elements\n\"c830c578-8f97-4036-b082-89feda876131\" = true\n\n# set is a subset of larger set with same elements\n\"476a4a1c-0fd1-430f-aa65-5b70cbc810c5\" = true\n\n# set is not a subset of set that does not contain its elements\n\"d2498999-3e46-48e4-9660-1e20c3329d3d\" = true\n\n# the empty set is disjoint with itself\n\"7d38155e-f472-4a7e-9ad8-5c1f8f95e4cc\" = true\n\n# empty set is disjoint with non-empty set\n\"7a2b3938-64b6-4b32-901a-fe16891998a6\" = true\n\n# non-empty set is disjoint with empty set\n\"589574a0-8b48-48ea-88b0-b652c5fe476f\" = true\n\n# sets are not disjoint if they share an element\n\"febeaf4f-f180-4499-91fa-59165955a523\" = true\n\n# sets are disjoint if they share no elements\n\"0de20d2f-c952-468a-88c8-5e056740f020\" = true\n\n# empty sets are equal\n\"4bd24adb-45da-4320-9ff6-38c044e9dff8\" = true\n\n# empty set is not equal to non-empty set\n\"f65c0a0e-6632-4b2d-b82c-b7c6da2ec224\" = true\n\n# non-empty set is not equal to empty set\n\"81e53307-7683-4b1e-a30c-7e49155fe3ca\" = true\n\n# sets with the same elements are equal\n\"d57c5d7c-a7f3-48cc-a162-6b488c0fbbd0\" = true\n\n# sets with different elements are not equal\n\"dd61bafc-6653-42cc-961a-ab071ee0ee85\" = true\n\n# set is not equal to larger set with same elements\n\"06059caf-9bf4-425e-aaff-88966cb3ea14\" = true\n\n# add to empty set\n\"8a677c3c-a658-4d39-bb88-5b5b1a9659f4\" = true\n\n# add to non-empty set\n\"0903dd45-904d-4cf2-bddd-0905e1a8d125\" = true\n\n# adding an existing element does not change the set\n\"b0eb7bb7-5e5d-4733-b582-af771476cb99\" = true\n\n# intersection of two empty sets is an empty set\n\"893d5333-33b8-4151-a3d4-8f273358208a\" = true\n\n# intersection of an empty set and non-empty set is an empty set\n\"d739940e-def2-41ab-a7bb-aaf60f7d782c\" = true\n\n# intersection of a non-empty set and an empty set is an empty set\n\"3607d9d8-c895-4d6f-ac16-a14956e0a4b7\" = true\n\n# intersection of two sets with no shared elements is an empty set\n\"b5120abf-5b5e-41ab-aede-4de2ad85c34e\" = true\n\n# intersection of two sets with shared elements is a set of the shared elements\n\"af21ca1b-fac9-499c-81c0-92a591653d49\" = true\n\n# difference of two empty sets is an empty set\n\"c5e6e2e4-50e9-4bc2-b89f-c518f015b57e\" = true\n\n# difference of empty set and non-empty set is an empty set\n\"2024cc92-5c26-44ed-aafd-e6ca27d6fcd2\" = true\n\n# difference of a non-empty set and an empty set is the non-empty set\n\"e79edee7-08aa-4c19-9382-f6820974b43e\" = true\n\n# difference of two non-empty sets is a set of elements that are only in the first set\n\"c5ac673e-d707-4db5-8d69-7082c3a5437e\" = true\n\n# union of empty sets is an empty set\n\"c45aed16-5494-455a-9033-5d4c93589dc6\" = true\n\n# union of an empty set and non-empty set is the non-empty set\n\"9d258545-33c2-4fcb-a340-9f8aa69e7a41\" = true\n\n# union of a non-empty set and empty set is the non-empty set\n\"3aade50c-80c7-4db8-853d-75bac5818b83\" = true\n\n# union of non-empty sets contains all unique elements\n\"a00bb91f-c4b4-4844-8f77-c73e2e9df77c\" = true\n"
  },
  {
    "path": "exercises/practice/custom-set/.meta/version",
    "content": "1.3.0\n"
  },
  {
    "path": "exercises/practice/custom-set/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/custom-set/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/custom-set/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/custom-set/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/custom-set/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/custom-set/src/main/kotlin/CustomSet.kt",
    "content": "class CustomSet() {\n\n    // TODO: implement proper constructor\n\n    fun isEmpty(): Boolean {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun isSubset(other: CustomSet): Boolean {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun isDisjoint(other: CustomSet): Boolean {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun contains(other: Int): Boolean {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun intersection(other: CustomSet): CustomSet {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun add(other: Int) {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    override fun equals(other: Any?): Boolean {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    operator fun plus(other: CustomSet): CustomSet {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    operator fun minus(other: CustomSet): CustomSet {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/custom-set/src/test/kotlin/CustomSetTest.kt",
    "content": "import kotlin.test.Test\nimport kotlin.test.assertEquals\nimport kotlin.test.assertFalse\nimport kotlin.test.assertNotEquals\nimport kotlin.test.assertTrue\nimport kotlin.test.Ignore\n\nclass CustomSetTest {\n\n    @Test\n    fun `sets with no elements are empty`() {\n        val sut = CustomSet()\n        assertTrue(sut.isEmpty())\n    }\n\n    @Ignore\n    @Test\n    fun `sets with elements are not empty`() {\n        val sut = CustomSet(1)\n        assertFalse(sut.isEmpty())\n    }\n\n    @Ignore\n    @Test\n    fun `nothing is contained in an empty set`() {\n        val sut = CustomSet()\n        assertFalse(sut.contains(1))\n    }\n\n    @Ignore\n    @Test\n    fun `when the element is in the set`() {\n        val sut = CustomSet(1, 2, 3)\n        assertTrue(sut.contains(1))\n    }\n\n    @Ignore\n    @Test\n    fun `when the element is not in the set`() {\n        val sut = CustomSet(1, 2, 3)\n        assertFalse(sut.contains(4))\n    }\n\n    @Ignore\n    @Test\n    fun `empty set is a subset of another empty set`() {\n        val set1 = CustomSet()\n        val set2 = CustomSet()\n        assertTrue(set1.isSubset(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `empty set is a subset of non empty set`() {\n        val set1 = CustomSet()\n        val set2 = CustomSet(1)\n        assertTrue(set1.isSubset(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `non empty set is not a subset of empty set`() {\n        val set1 = CustomSet(1)\n        val set2 = CustomSet()\n        assertFalse(set1.isSubset(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `set is a subset of set with exact same elements`() {\n        val set1 = CustomSet(1, 2, 3)\n        val set2 = CustomSet(1, 2, 3)\n        assertTrue(set1.isSubset(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `set is a subset of larger set with same elements`() {\n        val set1 = CustomSet(1, 2, 3)\n        val set2 = CustomSet(4, 1, 2, 3)\n        assertTrue(set1.isSubset(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `set is not a subset of set that does not contain its elements`() {\n        val set1 = CustomSet(1, 2, 3)\n        val set2 = CustomSet(4, 1, 3)\n        assertFalse(set1.isSubset(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `the empty set is disjoint with itself`() {\n        val set1 = CustomSet()\n        val set2 = CustomSet()\n        assertTrue(set1.isDisjoint(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `empty set is disjoint with non empty set`() {\n        val set1 = CustomSet()\n        val set2 = CustomSet(1)\n        assertTrue(set1.isDisjoint(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `non empty set is disjoint with empty set`() {\n        val set1 = CustomSet(1)\n        val set2 = CustomSet()\n        assertTrue(set1.isDisjoint(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `sets are not disjoint if they share an element`() {\n        val set1 = CustomSet(1, 2)\n        val set2 = CustomSet(2, 3)\n        assertFalse(set1.isDisjoint(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `sets are disjoint if they share no elements`() {\n        val set1 = CustomSet(1, 2)\n        val set2 = CustomSet(3, 4)\n        assertTrue(set1.isDisjoint(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `empty sets are equal`() {\n        val set1 = CustomSet()\n        val set2 = CustomSet()\n        assertEquals(set1, set2)\n    }\n\n    @Ignore\n    @Test\n    fun `empty set is not equal to non empty set`() {\n        val set1 = CustomSet()\n        val set2 = CustomSet(1, 2, 3)\n        assertNotEquals(set1, set2)\n    }\n\n    @Ignore\n    @Test\n    fun `non empty set is not equal to empty set`() {\n        val set1 = CustomSet(1, 2, 3)\n        val set2 = CustomSet()\n        assertNotEquals(set1, set2)\n    }\n\n    @Ignore\n    @Test\n    fun `sets with the same elements are equal`() {\n        val set1 = CustomSet(1, 2)\n        val set2 = CustomSet(2, 1)\n        assertEquals(set1, set2)\n\n    }\n\n    @Ignore\n    @Test\n    fun `sets with different elements are not equal`() {\n        val set1 = CustomSet(1, 2, 3)\n        val set2 = CustomSet(1, 2, 4)\n        assertNotEquals(set1, set2)\n    }\n\n    @Ignore\n    @Test\n    fun `set is not equal to larger set with same elements`() {\n        val set1 = CustomSet(1, 2, 3)\n        val set2 = CustomSet(1, 2, 3, 4)\n        assertNotEquals(set1, set2)\n    }\n\n    @Ignore\n    @Test\n    fun `add to empty set`() {\n        val sut = CustomSet()\n        val expected = CustomSet(3)\n        sut.add(3)\n        assertEquals(expected, sut)\n    }\n\n    @Ignore\n    @Test\n    fun `add to non empty set`() {\n        val sut = CustomSet(1, 2, 4)\n        val expected = CustomSet(1, 2, 3, 4)\n        sut.add(3)\n        assertEquals(expected, sut)\n    }\n\n    @Ignore\n    @Test\n    fun `adding an existing element does not change the set`() {\n        val sut = CustomSet(1, 2, 3)\n        val expected = CustomSet(1, 2, 3)\n        sut.add(3)\n        assertEquals(expected, sut)\n    }\n\n    @Ignore\n    @Test\n    fun `intersection of two empty sets is an empty set`() {\n        val set1 = CustomSet()\n        val set2 = CustomSet()\n        val expected = CustomSet()\n        assertEquals(expected, set1.intersection(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `intersection of an empty set and non empty set is an empty set`() {\n        val set1 = CustomSet()\n        val set2 = CustomSet(3, 2, 5)\n        val expected = CustomSet()\n        assertEquals(expected, set1.intersection(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `intersection of a non empty set and an empty set is an empty set`() {\n        val set1 = CustomSet(1, 2, 3, 4)\n        val set2 = CustomSet()\n        val expected = CustomSet()\n        assertEquals(expected, set1.intersection(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `intersection of two sets with no shared elements is an empty set`() {\n        val set1 = CustomSet(1, 2, 3)\n        val set2 = CustomSet(4, 5, 6)\n        val expected = CustomSet()\n        assertEquals(expected, set1.intersection(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `intersection of two sets with shared elements is a set of the shared elements`() {\n        val set1 = CustomSet(1, 2, 3, 4)\n        val set2 = CustomSet(3, 2, 5)\n        val expected = CustomSet(2, 3)\n        assertEquals(expected, set1.intersection(set2))\n    }\n\n    @Ignore\n    @Test\n    fun `difference of two empty sets is an empty set`() {\n        val set1 = CustomSet()\n        val set2 = CustomSet()\n        val expected = CustomSet()\n        assertEquals(expected, set1 - set2)\n    }\n\n    @Ignore\n    @Test\n    fun `difference of empty set and non empty set is an empty set`() {\n        val set1 = CustomSet()\n        val set2 = CustomSet(3, 2, 5)\n        val expected = CustomSet()\n        assertEquals(expected, set1 - set2)\n    }\n\n    @Ignore\n    @Test\n    fun `difference of a non empty set and an empty set is the non empty set`() {\n        val set1 = CustomSet(1, 2, 3, 4)\n        val set2 = CustomSet()\n        val expected = CustomSet(1, 2, 3, 4)\n        assertEquals(expected, set1 - set2)\n    }\n\n    @Ignore\n    @Test\n    fun `difference of two non empty sets is a set of elements that are only in the first set`() {\n        val set1 = CustomSet(3, 2, 1)\n        val set2 = CustomSet(2, 4)\n        val expected = CustomSet(1, 3)\n        assertEquals(expected, set1 - set2)\n    }\n\n    @Ignore\n    @Test\n    fun `union of empty sets is an empty set`() {\n        val set1 = CustomSet()\n        val set2 = CustomSet()\n        val expected = CustomSet()\n        assertEquals(expected, set1 + set2)\n    }\n\n    @Ignore\n    @Test\n    fun `union of an empty set and non empty set is the non empty set`() {\n        val set1 = CustomSet()\n        val set2 = CustomSet(2)\n        val expected = CustomSet(2)\n        assertEquals(expected, set1 + set2)\n    }\n\n    @Ignore\n    @Test\n    fun `union of a non empty set and empty set is the non empty set`() {\n        val set1 = CustomSet(1, 3)\n        val set2 = CustomSet()\n        val expected = CustomSet(1, 3)\n        assertEquals(expected, set1 + set2)\n    }\n\n    @Ignore\n    @Test\n    fun `union of non empty sets contains all unique elements`() {\n        val set1 = CustomSet(1, 3)\n        val set2 = CustomSet(2, 3)\n        val expected = CustomSet(3, 2, 1)\n        assertEquals(expected, set1 + set2)\n    }\n}\n"
  },
  {
    "path": "exercises/practice/darts/.approaches/config.json",
    "content": "{\n  \"introduction\": {\n    \"authors\": [\n      \"bobahop\"\n    ]\n  },\n  \"approaches\": [\n    {\n      \"uuid\": \"40396c67-efdd-4031-bbfd-12e92e7448c8\",\n      \"slug\": \"hypot-for-radius\",\n      \"title\": \"hypot for radius\",\n      \"blurb\": \"Use the hypot function to get the radius of the throw.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "exercises/practice/darts/.approaches/hypot-for-radius/content.md",
    "content": "# `hypot` for radius\n\n```kotlin\nimport kotlin.math.hypot\n\nobject Darts {\n    private const val innerRing = 1.0\n    private const val middleRing = 5.0\n    private const val outerRing = 10.0\n\n    fun score(x: Number, y: Number): Int {\n        val toss = hypot(x.toDouble(), y.toDouble())\n        fun throwWithin(ring: Double) = toss <= ring\n\n        if (throwWithin(innerRing)) return 10\n        if (throwWithin(middleRing)) return 5\n        if (throwWithin(outerRing)) return 1\n        return 0\n    }\n}\n```\n\nAn [object declaration][object] is used to define `Darts` as essentially a [singleton][singleton] object instantiation of the class.\nThis is sufficient, since there is no object state that needs to change with each call of the `score` method.\n\nThe object defines [private][visibility] [`const`][const] [val][variables]s for the rings.\nThe `const` values are given meaningful names instead of using the float literals as [magic numbers][magic-numbers].\nA `val` is immutable, as is a `const`.\nA `const` `val` means that the value of the `val` is known at compile time.\n\nThe [`hypot`][hypot] function is used to calculate the [radius][radius] of the dart throw from the `x` and `y` coordinates.\n\nThe `throwWithin` function returns if the radius is within the ring passed in.\n\nDue to the naming of the function and varables, the `if` statements read much like natural language.\n\nThe `throwWithin` function is passed the ring.\nIf it returns `true`, then the function returns with the score for throwing within that ring.\n\nIf the throw is not within a defined ring, then the function returns `0`.\n\n[object]: https://kotlinlang.org/docs/object-declarations.html#object-declarations-overview\n[singleton]: https://en.wikipedia.org/wiki/Singleton_pattern\n[visibility]: https://kotlinlang.org/docs/visibility-modifiers.html\n[const]: https://www.geeksforgeeks.org/whats-the-difference-between-const-and-val-in-kotlin/\n[variables]: https://kotlinlang.org/docs/basic-syntax.html#variables\n[magic-numbers]: https://en.wikipedia.org/wiki/Magic_number_(programming)\n[hypot]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.math/hypot.html\n[radius]: https://www.mathopenref.com/coordbasiccircle.html\n\n"
  },
  {
    "path": "exercises/practice/darts/.approaches/hypot-for-radius/snippet.txt",
    "content": "val toss = hypot(x.toDouble(), y.toDouble())\nfun throwWithin(ring: Double) = toss <= ring\n\nif (throwWithin(innerRing)) return 10\nif (throwWithin(middleRing)) return 5\nif (throwWithin(outerRing)) return 1\nreturn 0\n"
  },
  {
    "path": "exercises/practice/darts/.approaches/introduction.md",
    "content": "# Introduction\n\nThere are several ways to solve Darts.\nOne approach is to use the [`hypot`][hypot] function to get the [radius][radius] of the throw.\n\n## Approach: `hypot` for radius\n\n```kotlin\nimport kotlin.math.hypot\n\nobject Darts {\n    private const val innerRing = 1.0\n    private const val middleRing = 5.0\n    private const val outerRing = 10.0\n\n    fun score(x: Number, y: Number): Int {\n        val toss = hypot(x.toDouble(), y.toDouble())\n        fun throwWithin(ring: Double) = toss <= ring\n\n        if (throwWithin(innerRing)) return 10\n        if (throwWithin(middleRing)) return 5\n        if (throwWithin(outerRing)) return 1\n        return 0\n    }\n}\n```\n\nFor more information, check the [`hypot` for radius approach][approach-hypot-for-radius].\n\n[approach-hypot-for-radius]: https://exercism.org/tracks/kotlin/exercises/darts/approaches/hypot-for-radius\n[hypot]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.math/hypot.html\n[radius]: https://www.mathopenref.com/coordbasiccircle.html\n"
  },
  {
    "path": "exercises/practice/darts/.docs/instructions.md",
    "content": "# Instructions\n\nCalculate the points scored in a single toss of a Darts game.\n\n[Darts][darts] is a game where players throw darts at a [target][darts-target].\n\nIn our particular instance of the game, the target rewards 4 different amounts of points, depending on where the dart lands:\n\n![Our dart scoreboard with values from a complete miss to a bullseye](https://assets.exercism.org/images/exercises/darts/darts-scoreboard.svg)\n\n- If the dart lands outside the target, player earns no points (0 points).\n- If the dart lands in the outer circle of the target, player earns 1 point.\n- If the dart lands in the middle circle of the target, player earns 5 points.\n- If the dart lands in the inner circle of the target, player earns 10 points.\n\nThe 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.\nOf course, they are all centered at the same point — that is, the circles are [concentric][] defined by the coordinates (0, 0).\n\nGiven 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.\n\n## Credit\n\nThe scoreboard image was created by [habere-et-dispertire][habere-et-dispertire] using [Inkscape][inkscape].\n\n[darts]: https://en.wikipedia.org/wiki/Darts\n[darts-target]: https://en.wikipedia.org/wiki/Darts#/media/File:Darts_in_a_dartboard.jpg\n[concentric]: https://mathworld.wolfram.com/ConcentricCircles.html\n[cartesian-coordinates]: https://www.mathsisfun.com/data/cartesian-coordinates.html\n[real-numbers]: https://www.mathsisfun.com/numbers/real-numbers.html\n[habere-et-dispertire]: https://exercism.org/profiles/habere-et-dispertire\n[inkscape]: https://en.wikipedia.org/wiki/Inkscape\n"
  },
  {
    "path": "exercises/practice/darts/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Darts.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/DartsTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Darts.kt\"\n    ]\n  },\n  \"blurb\": \"Calculate the points scored in a single toss of a Darts game.\",\n  \"source\": \"Inspired by an exercise created by a professor Della Paolera in Argentina\"\n}\n"
  },
  {
    "path": "exercises/practice/darts/.meta/src/reference/kotlin/Darts.kt",
    "content": "import kotlin.math.pow\nimport kotlin.math.sqrt\n\nobject Darts {\n\n    /** Return the correct amount earned by a dart's landing position. */\n    fun score(x: Number, y: Number): Int {\n        val r = sqrt(x.toDouble().pow(2.0) + y.toDouble().pow(2.0)) // Pythagoras\n        return when {\n            r <= 1 -> 10\n            r <= 5 -> 5\n            r <= 10 -> 1\n            else -> 0\n        }\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/darts/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# Missed target\n\"9033f731-0a3a-4d9c-b1c0-34a1c8362afb\" = true\n\n# On the outer circle\n\"4c9f6ff4-c489-45fd-be8a-1fcb08b4d0ba\" = true\n\n# On the middle circle\n\"14378687-ee58-4c9b-a323-b089d5274be8\" = true\n\n# On the inner circle\n\"849e2e63-85bd-4fed-bc3b-781ae962e2c9\" = true\n\n# Exactly on centre\n\"1c5ffd9f-ea66-462f-9f06-a1303de5a226\" = true\n\n# Near the centre\n\"b65abce3-a679-4550-8115-4b74bda06088\" = true\n\n# Just within the inner circle\n\"66c29c1d-44f5-40cf-9927-e09a1305b399\" = true\n\n# Just outside the inner circle\n\"d1012f63-c97c-4394-b944-7beb3d0b141a\" = true\n\n# Just within the middle circle\n\"ab2b5666-b0b4-49c3-9b27-205e790ed945\" = true\n\n# Just outside the middle circle\n\"70f1424e-d690-4860-8caf-9740a52c0161\" = true\n\n# Just within the outer circle\n\"a7dbf8db-419c-4712-8a7f-67602b69b293\" = true\n\n# Just outside the outer circle\n\"e0f39315-9f9a-4546-96e4-a9475b885aa7\" = true\n\n# Asymmetric position between the inner and middle circles\n\"045d7d18-d863-4229-818e-b50828c75d19\" = true\n"
  },
  {
    "path": "exercises/practice/darts/.meta/version",
    "content": "2.2.0\n"
  },
  {
    "path": "exercises/practice/darts/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/darts/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/darts/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/darts/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/darts/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/darts/src/main/kotlin/Darts.kt",
    "content": "object Darts {\n\n    fun score(x: Any, y: Any /* choose proper types! */): Int {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/darts/src/test/kotlin/DartsTest.kt",
    "content": "import kotlin.test.Ignore\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\n\nclass DartsTest {\n\n    @Test\n    fun `missed target`() = assertEquals(0, Darts.score(-9, 9))\n\n    @Ignore\n    @Test\n    fun `on the outer circle`() = assertEquals(1, Darts.score(0, 10))\n\n    @Ignore\n    @Test\n    fun `on the middle circle`() = assertEquals(5, Darts.score(-5, 0))\n\n    @Ignore\n    @Test\n    fun `on the inner circle`() = assertEquals(10, Darts.score(0, -1))\n\n    @Ignore\n    @Test\n    fun `exactly on centre`() = assertEquals(10, Darts.score(0, 0))\n\n    @Ignore\n    @Test\n    fun `near the centre`() = assertEquals(10, Darts.score(-0.1, -0.1))\n\n    @Ignore\n    @Test\n    fun `just within the inner circle`() = assertEquals(10, Darts.score(0.7, 0.7))\n\n    @Ignore\n    @Test\n    fun `just outside the inner circle`() = assertEquals(5, Darts.score(0.8, -0.8))\n\n    @Ignore\n    @Test\n    fun `just within the middle circle`() = assertEquals(5, Darts.score(-3.5, 3.5))\n\n    @Ignore\n    @Test\n    fun `just outside the middle circle`() = assertEquals(1, Darts.score(-3.6, -3.6))\n\n    @Ignore\n    @Test\n    fun `just within the outer circle`() = assertEquals(1, Darts.score(-7.0, 7.0))\n\n    @Ignore\n    @Test\n    fun `just outside the outer circle`() = assertEquals(0, Darts.score(7.1, -7.1))\n\n    @Ignore\n    @Test\n    fun `asymmetric position between the inner and middle circles`() = assertEquals(5, Darts.score(0.5, -4))\n}\n"
  },
  {
    "path": "exercises/practice/diamond/.docs/instructions.md",
    "content": "# Instructions\n\nThe diamond kata takes as its input a letter, and outputs it in a diamond shape.\nGiven a letter, it prints a diamond starting with 'A', with the supplied letter at the widest point.\n\n## Requirements\n\n- The first row contains one 'A'.\n- The last row contains one 'A'.\n- All rows, except the first and last, have exactly two identical letters.\n- All rows have as many trailing spaces as leading spaces. (This might be 0).\n- The diamond is horizontally symmetric.\n- The diamond is vertically symmetric.\n- The diamond has a square shape (width equals height).\n- The letters form a diamond shape.\n- The top half has the letters in ascending order.\n- The bottom half has the letters in descending order.\n- The four corners (containing the spaces) are triangles.\n\n## Examples\n\nIn the following examples, spaces are indicated by `·` characters.\n\nDiamond for letter 'A':\n\n```text\nA\n```\n\nDiamond for letter 'C':\n\n```text\n··A··\n·B·B·\nC···C\n·B·B·\n··A··\n```\n\nDiamond for letter 'E':\n\n```text\n····A····\n···B·B···\n··C···C··\n·D·····D·\nE·······E\n·D·····D·\n··C···C··\n···B·B···\n····A····\n```\n"
  },
  {
    "path": "exercises/practice/diamond/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/DiamondPrinter.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/DiamondPrinterTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/DiamondPrinter.kt\"\n    ]\n  },\n  \"blurb\": \"Given a letter, print a diamond starting with 'A' with the supplied letter at the widest point.\",\n  \"source\": \"Seb Rose\",\n  \"source_url\": \"https://web.archive.org/web/20220807163751/http://claysnow.co.uk/recycling-tests-in-tdd/\"\n}\n"
  },
  {
    "path": "exercises/practice/diamond/.meta/src/reference/kotlin/DiamondPrinter.kt",
    "content": "import java.util.*\n\nclass DiamondPrinter {\n\n    companion object {\n        private const val A_INT = 'A'.code\n\n        private fun blank(length: Int): String {\n            return Collections.nCopies(length, \" \").joinToString(\"\")\n        }\n    }\n\n    fun printToList(chr: Char): List<String> {\n        val nRows = 2 * (chr.code - A_INT) + 1\n\n        val result = mutableListOf<String>()\n\n        // Populate the top rows.\n        for (nRow in 0 until (nRows + 1) / 2) {\n            val rowChr = (A_INT + nRow).toChar()\n\n            val leftHalfOfRow = blank((nRows - 1) / 2 - nRow) + rowChr + blank(nRow)\n            val rightHalfOfRow = leftHalfOfRow.reversed().drop(1)\n            val fullRow = \"$leftHalfOfRow$rightHalfOfRow\"\n\n            result.add(fullRow)\n        }\n\n        // Populate the bottom rows by 'reflecting' all rows above the middle row.\n        result.addAll(result.reversed().drop(1))\n\n        return result\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/diamond/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# Degenerate case with a single 'A' row\n\"202fb4cc-6a38-4883-9193-a29d5cb92076\" = true\n\n# Degenerate case with no row containing 3 distinct groups of spaces\n\"bd6a6d78-9302-42e9-8f60-ac1461e9abae\" = true\n\n# Smallest non-degenerate case with odd diamond side length\n\"af8efb49-14ed-447f-8944-4cc59ce3fd76\" = true\n\n# Smallest non-degenerate case with even diamond side length\n\"e0c19a95-9888-4d05-86a0-fa81b9e70d1d\" = true\n\n# Largest possible diamond\n\"82ea9aa9-4c0e-442a-b07e-40204e925944\" = true\n"
  },
  {
    "path": "exercises/practice/diamond/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/diamond/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/diamond/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/diamond/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/diamond/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/diamond/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/diamond/src/main/kotlin/DiamondPrinter.kt",
    "content": "class DiamondPrinter {\n\n\n\n}\n"
  },
  {
    "path": "exercises/practice/diamond/src/test/kotlin/DiamondPrinterTest.kt",
    "content": "import org.hamcrest.CoreMatchers.`is`\nimport org.hamcrest.MatcherAssert.assertThat\nimport org.junit.Before\nimport org.junit.Ignore\nimport org.junit.Test\n\nclass DiamondPrinterTest {\n\n    private lateinit var diamondPrinter: DiamondPrinter\n\n    @Before\n    fun setUp() {\n        diamondPrinter = DiamondPrinter()\n    }\n\n    @Test\n    fun testOneByOneDiamond() {\n        val output = diamondPrinter.printToList('A')\n        assertThat(output, `is`(listOf(\"A\")))\n    }\n\n    @Ignore\n    @Test\n    fun testTwoByTwoDiamond() {\n        val output = diamondPrinter.printToList('B')\n        assertThat(output, `is`(listOf(\n                \" A \",\n                \"B B\",\n                \" A \")))\n    }\n\n    @Ignore\n    @Test\n    fun testThreeByThreeDiamond() {\n        val output = diamondPrinter.printToList('C')\n        assertThat(output, `is`(listOf(\n                \"  A  \",\n                \" B B \",\n                \"C   C\",\n                \" B B \",\n                \"  A  \")))\n    }\n\n    @Ignore\n    @Test\n    fun testFiveByFiveDiamond() {\n        val output = diamondPrinter.printToList('E')\n        assertThat(output, `is`(listOf(\n                \"    A    \",\n                \"   B B   \",\n                \"  C   C  \",\n                \" D     D \",\n                \"E       E\",\n                \" D     D \",\n                \"  C   C  \",\n                \"   B B   \",\n                \"    A    \")))\n    }\n\n    @Ignore\n    @Test\n    fun testFullDiamond() {\n        val output = diamondPrinter.printToList('Z')\n        assertThat(output, `is`(listOf(\n                \"                         A                         \",\n                \"                        B B                        \",\n                \"                       C   C                       \",\n                \"                      D     D                      \",\n                \"                     E       E                     \",\n                \"                    F         F                    \",\n                \"                   G           G                   \",\n                \"                  H             H                  \",\n                \"                 I               I                 \",\n                \"                J                 J                \",\n                \"               K                   K               \",\n                \"              L                     L              \",\n                \"             M                       M             \",\n                \"            N                         N            \",\n                \"           O                           O           \",\n                \"          P                             P          \",\n                \"         Q                               Q         \",\n                \"        R                                 R        \",\n                \"       S                                   S       \",\n                \"      T                                     T      \",\n                \"     U                                       U     \",\n                \"    V                                         V    \",\n                \"   W                                           W   \",\n                \"  X                                             X  \",\n                \" Y                                               Y \",\n                \"Z                                                 Z\",\n                \" Y                                               Y \",\n                \"  X                                             X  \",\n                \"   W                                           W   \",\n                \"    V                                         V    \",\n                \"     U                                       U     \",\n                \"      T                                     T      \",\n                \"       S                                   S       \",\n                \"        R                                 R        \",\n                \"         Q                               Q         \",\n                \"          P                             P          \",\n                \"           O                           O           \",\n                \"            N                         N            \",\n                \"             M                       M             \",\n                \"              L                     L              \",\n                \"               K                   K               \",\n                \"                J                 J                \",\n                \"                 I               I                 \",\n                \"                  H             H                  \",\n                \"                   G           G                   \",\n                \"                    F         F                    \",\n                \"                     E       E                     \",\n                \"                      D     D                      \",\n                \"                       C   C                       \",\n                \"                        B B                        \",\n                \"                         A                         \")))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/.approaches/config.json",
    "content": "{\n  \"introduction\": {\n    \"authors\": [\n      \"bobahop\"\n    ]\n  },\n  \"approaches\": [\n    {\n      \"uuid\": \"862a595e-613f-4172-87f1-95c04e0051de\",\n      \"slug\": \"formula\",\n      \"title\": \"Formula\",\n      \"blurb\": \"Use a formula to calculate a solution.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/.approaches/formula/content.md",
    "content": "# Use formula\n\n```kotlin\nclass Squares(private val input: Int) {\n\n    fun squareOfSum() = (input * (input + 1) / 2).let { it * it }\n\n    fun sumOfSquares() = (input * (input + 1) * ((input * 2) + 1)) / 6\n\n    fun difference() = squareOfSum() - sumOfSquares()\n}\n```\n\nA [`private`][visibility] [`val`][variables] is defined as the parameter for the primary [constructor][constructors].\n\nIn this solution a [formula][formula] is used to solve the `squareOfSum` and `sumOfSquares` methods.\n\nAt the time of this writing the instructions state:\n\n>You are not expected to discover an efficient solution to this yourself from first principles; \n>research is allowed, indeed, encouraged. Finding the best algorithm for the problem is a key skill in software engineering.\n\nIt is fine to search for an algorithm on the internet.\nThis is also sometimes referred to as [\"Google is your friend\"][google-friend], although you don't have to search with Google.\n\nIt is okay if you don't understand how the algorithm works.\nWhat is important is that it obviously is not introducing malware and that it passes the tests.\n\nNote that this avoids using [`pow`][pow] in `squareOfSum`,\nsince multiplying a value by itself is usually more efficient than type-casting from `int `to `double` back to `int`.\nInstead, it uses the [`it`][it] keyword to refer to the value multiplied by itself in the [`let`][let] function.\n\n[constructors]: https://www.geeksforgeeks.org/kotlin-constructor/\n[visibility]: https://kotlinlang.org/docs/visibility-modifiers.html\n[variables]: https://kotlinlang.org/docs/basic-syntax.html#variables\n[formula]: https://learnersbucket.com/examples/algorithms/difference-between-square-of-sum-of-numbers-and-sum-of-square-of-numbers/\n[google-friend]: https://en.wiktionary.org/wiki/Google_is_your_friend\n[pow]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.math/pow.html\n[let]: https://kotlinlang.org/docs/scope-functions.html#let\n[it]: https://kotlinlang.org/docs/lambdas.html#it-implicit-name-of-a-single-parameter\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/.approaches/formula/snippet.txt",
    "content": "class Squares(private val input: Int) {\n\n    fun squareOfSum() = (input * (input + 1) / 2).let { it * it }\n\n    fun sumOfSquares() = (input * (input + 1) * ((input * 2) + 1)) / 6\n\n    fun difference() = squareOfSum() - sumOfSquares()\n}\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/.approaches/introduction.md",
    "content": "# Introduction\n\nThere are various ways to solve Difference of Squares.\nOne approach is to use a [formula][formula] to calculate the solution.\n\n## Approach: Use formula\n\n```kotlin\nclass Squares(private val input: Int) {\n\n    fun squareOfSum() = (input * (input + 1) / 2).let { it * it }\n\n    fun sumOfSquares() = (input * (input + 1) * ((input * 2) + 1)) / 6\n\n    fun difference() = squareOfSum() - sumOfSquares()\n}\n```\n\nFor more information, check the [formula approach][approach-formula].\n\n[formula]: https://learnersbucket.com/examples/algorithms/difference-between-square-of-sum-of-numbers-and-sum-of-square-of-numbers/\n[approach-formula]: https://exercism.org/tracks/kotlin/exercises/difference-of-squares/approaches/formula\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/.docs/instructions.md",
    "content": "# Instructions\n\nFind the difference between the square of the sum and the sum of the squares of the first N natural numbers.\n\nThe square of the sum of the first ten natural numbers is\n(1 + 2 + ... + 10)² = 55² = 3025.\n\nThe sum of the squares of the first ten natural numbers is\n1² + 2² + ... + 10² = 385.\n\nHence the difference between the square of the sum of the first ten natural numbers and the sum of the squares of the first ten natural numbers is 3025 - 385 = 2640.\n\nYou are not expected to discover an efficient solution to this yourself from first principles; research is allowed, indeed, encouraged.\nFinding the best algorithm for the problem is a key skill in software engineering.\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/DifferenceOfSquares.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/SquaresTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/DifferenceOfSquares.kt\"\n    ]\n  },\n  \"blurb\": \"Find the difference between the square of the sum and the sum of the squares of the first N natural numbers.\",\n  \"source\": \"Problem 6 at Project Euler\",\n  \"source_url\": \"https://projecteuler.net/problem=6\"\n}\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/.meta/src/reference/kotlin/DifferenceOfSquares.kt",
    "content": "class Squares(private val max: Int) {\n    private val range = 1..max\n\n    fun sumOfSquares() = range.sumOf { it.squared() }\n    fun squareOfSum() = range.sum().squared()\n    fun difference() = squareOfSum() - sumOfSquares()\n\n    private fun Int.squared() = this * this\n}\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# square of sum 1\n\"e46c542b-31fc-4506-bcae-6b62b3268537\" = true\n\n# square of sum 5\n\"9b3f96cb-638d-41ee-99b7-b4f9c0622948\" = true\n\n# square of sum 100\n\"54ba043f-3c35-4d43-86ff-3a41625d5e86\" = true\n\n# sum of squares 1\n\"01d84507-b03e-4238-9395-dd61d03074b5\" = true\n\n# sum of squares 5\n\"c93900cd-8cc2-4ca4-917b-dd3027023499\" = true\n\n# sum of squares 100\n\"94807386-73e4-4d9e-8dec-69eb135b19e4\" = true\n\n# difference of squares 1\n\"44f72ae6-31a7-437f-858d-2c0837adabb6\" = true\n\n# difference of squares 5\n\"005cb2bf-a0c8-46f3-ae25-924029f8b00b\" = true\n\n# difference of squares 100\n\"b1bf19de-9a16-41c0-a62b-1f02ecc0b036\" = true\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/.meta/version",
    "content": "1.2.0\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/src/main/kotlin/DifferenceOfSquares.kt",
    "content": "class Squares {\n    //TODO: implement proper constructor\n\n    fun sumOfSquares() {\n        TODO(\"Implement the function to complete the task\")\n    }\n\n    fun squareOfSum() {\n        TODO(\"Implement the function to complete the task\")\n    }\n\n    fun difference() {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/difference-of-squares/src/test/kotlin/SquaresTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass SquaresTest {\n\n    @Test\n    fun squareOfSum1() {\n        assertEquals(1, Squares(1).squareOfSum())\n    }\n\n    @Ignore\n    @Test\n    fun squareOfSum5() {\n        assertEquals(225, Squares(5).squareOfSum())\n    }\n\n    @Ignore\n    @Test\n    fun squareOfSum100() {\n        assertEquals(25502500, Squares(100).squareOfSum())\n    }\n\n    @Ignore\n    @Test\n    fun sumOfSquares1() {\n        assertEquals(1, Squares(1).sumOfSquares())\n    }\n\n    @Ignore\n    @Test\n    fun sumOfSquares5() {\n        assertEquals(55, Squares(5).sumOfSquares())\n    }\n\n    @Ignore\n    @Test\n    fun sumOfSquares100() {\n        assertEquals(338350, Squares(100).sumOfSquares())\n    }\n\n    @Ignore\n    @Test\n    fun differenceOfSquares1() {\n        assertEquals(0, Squares(1).difference())\n    }\n\n    @Ignore\n    @Test\n    fun differenceOfSquares5() {\n        assertEquals(170, Squares(5).difference())\n    }\n\n    @Ignore\n    @Test\n    fun differenceOfSquares100() {\n        assertEquals(25164150, Squares(100).difference())\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/diffie-hellman/.docs/instructions.md",
    "content": "# Instructions\n\nDiffie-Hellman key exchange.\n\nAlice and Bob use Diffie-Hellman key exchange to share secrets.\nThey start with prime numbers, pick private keys, generate and share public keys, and then generate a shared secret key.\n\n## Step 0\n\nThe test program supplies prime numbers p and g.\n\n## Step 1\n\nAlice picks a private key, a, greater than 1 and less than p.\nBob does the same to pick a private key b.\n\n## Step 2\n\nAlice calculates a public key A.\n\n    A = gᵃ mod p\n\nUsing the same p and g, Bob similarly calculates a public key B from his private key b.\n\n## Step 3\n\nAlice and Bob exchange public keys.\nAlice calculates secret key s.\n\n    s = Bᵃ mod p\n\nBob calculates\n\n    s = Aᵇ mod p\n\nThe calculations produce the same result!\nAlice and Bob now share secret s.\n"
  },
  {
    "path": "exercises/practice/diffie-hellman/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/DiffieHellman.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/DiffieHellmanTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/DiffieHellman.kt\"\n    ]\n  },\n  \"blurb\": \"Diffie-Hellman key exchange.\",\n  \"source\": \"Wikipedia, 1024 bit key from www.cryptopp.com/wiki.\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange\"\n}\n"
  },
  {
    "path": "exercises/practice/diffie-hellman/.meta/src/reference/kotlin/DiffieHellman.kt",
    "content": "import java.math.BigInteger\nimport java.util.Random\n\nobject DiffieHellman {\n\n    fun privateKey(prime: BigInteger): BigInteger {\n        val rnd = Random()\n        var bi: BigInteger\n        do {\n            bi = BigInteger(prime.bitCount(), rnd)\n        } while (bi == BigInteger.ZERO || bi.compareTo(prime) == 1)\n        return bi\n    }\n\n    fun publicKey(p: BigInteger, g: BigInteger, privKey: BigInteger): BigInteger {\n        return g.modPow(privKey, p)\n    }\n\n    fun secret(prime: BigInteger, publicKey: BigInteger, privateKey: BigInteger): BigInteger {\n        return publicKey.modPow(privateKey, prime)\n    }\n}\n"
  },
  {
    "path": "exercises/practice/diffie-hellman/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# private key is in range 1 .. p\n\"1b97bf38-4307-418e-bfd2-446ffc77588d\" = true\n\n# private key is random\n\"68b2a5f7-7755-44c3-97b2-d28d21f014a9\" = true\n\n# can calculate public key using private key\n\"b4161d8e-53a1-4241-ae8f-48cc86527f22\" = true\n\n# can calculate secret using other party's public key\n\"cd02ad45-3f52-4510-99cc-5161dad948a8\" = true\n\n# key exchange\n\"17f13c61-a111-4075-9a1f-c2d4636dfa60\" = true\n"
  },
  {
    "path": "exercises/practice/diffie-hellman/.meta/version",
    "content": "1.0.0\n"
  },
  {
    "path": "exercises/practice/diffie-hellman/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/diffie-hellman/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/diffie-hellman/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/diffie-hellman/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/diffie-hellman/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/diffie-hellman/src/main/kotlin/DiffieHellman.kt",
    "content": "import java.math.BigInteger\n\nobject DiffieHellman {\n\n    fun privateKey(prime: BigInteger): BigInteger {\n        TODO(\"Implement the function to complete the task\")\n    }\n\n    fun publicKey(p: BigInteger, g: BigInteger, privKey: BigInteger): BigInteger {\n        TODO(\"Implement the function to complete the task\")\n    }\n\n    fun secret(prime: BigInteger, publicKey: BigInteger, privateKey: BigInteger): BigInteger {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/diffie-hellman/src/test/kotlin/DiffieHellmanTest.kt",
    "content": "import org.junit.Test\nimport java.math.BigInteger\nimport kotlin.test.Ignore\nimport kotlin.test.assertEquals\nimport kotlin.test.assertNotEquals\nimport kotlin.test.assertTrue\n\nclass DiffieHellmanTest {\n\n    @Test\n    fun `private key is in range from 1 to prime`() {\n        val prime = 23.toBigInteger()\n        (0..9).map { DiffieHellman.privateKey(prime) }.forEach {\n            assertTrue(it >= BigInteger.ONE)\n            assertTrue(it < prime)\n        }\n    }\n\n    /**\n     * Due to the nature of randomness, there is always a chance that this test fails.\n     * Be sure to check the actual generated values.\n     */\n    @Ignore\n    @Test\n    fun `private key is random`() {\n        val prime = 7919.toBigInteger()\n        val privateKeyA = DiffieHellman.privateKey(prime)\n        val privateKeyB = DiffieHellman.privateKey(prime)\n\n        assertNotEquals(privateKeyA, privateKeyB)\n    }\n\n    @Ignore\n    @Test\n    fun `calculate public key using private key`() {\n        val primeA = 23.toBigInteger()\n        val primeB = 5.toBigInteger()\n        val privateKey = 6.toBigInteger()\n        val expected = 8.toBigInteger()\n\n        assertEquals(expected, DiffieHellman.publicKey(primeA, primeB, privateKey))\n    }\n\n\n    @Ignore\n    @Test\n    fun `calculate secret using other party's public key`() {\n        val prime = 23.toBigInteger()\n        val publicKey = 19.toBigInteger()\n        val privateKey = 6.toBigInteger()\n        val expected = 2.toBigInteger()\n\n        assertEquals(expected, DiffieHellman.secret(prime, publicKey, privateKey))\n    }\n\n\n    @Ignore\n    @Test\n    fun `key exchange`() {\n        val primeA = 23.toBigInteger()\n        val primeB = 5.toBigInteger()\n\n        val alicePrivateKey = DiffieHellman.privateKey(primeA)\n        val bobPrivateKey = DiffieHellman.privateKey(primeB)\n\n        val alicePublicKey = DiffieHellman.publicKey(primeA, primeB, alicePrivateKey)\n        val bobPublicKey = DiffieHellman.publicKey(primeA, primeB, bobPrivateKey)\n\n        val secretA = DiffieHellman.secret(primeA, bobPublicKey, alicePrivateKey)\n        val secretB = DiffieHellman.secret(primeA, alicePublicKey, bobPrivateKey)\n\n        assertEquals(secretA, secretB)\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/dnd-character/.docs/instructions.md",
    "content": "# Instructions\n\nFor a game of [Dungeons & Dragons][dnd], each player starts by generating a character they can play with.\nThis character has, among other things, six abilities; strength, dexterity, constitution, intelligence, wisdom and charisma.\nThese six abilities have scores that are determined randomly.\nYou do this by rolling four 6-sided dice and recording the sum of the largest three dice.\nYou do this six times, once for each ability.\n\nYour character's initial hitpoints are 10 + your character's constitution modifier.\nYou find your character's constitution modifier by subtracting 10 from your character's constitution, divide by 2 and round down.\n\nWrite a random character generator that follows the above rules.\n\nFor example, the six throws of four dice may look like:\n\n- 5, 3, 1, 6: You discard the 1 and sum 5 + 3 + 6 = 14, which you assign to strength.\n- 3, 2, 5, 3: You discard the 2 and sum 3 + 5 + 3 = 11, which you assign to dexterity.\n- 1, 1, 1, 1: You discard the 1 and sum 1 + 1 + 1 = 3, which you assign to constitution.\n- 2, 1, 6, 6: You discard the 1 and sum 2 + 6 + 6 = 14, which you assign to intelligence.\n- 3, 5, 3, 4: You discard the 3 and sum 5 + 3 + 4 = 12, which you assign to wisdom.\n- 6, 6, 6, 6: You discard the 6 and sum 6 + 6 + 6 = 18, which you assign to charisma.\n\nBecause constitution is 3, the constitution modifier is -4 and the hitpoints are 6.\n\n~~~~exercism/note\nMost programming languages feature (pseudo-)random generators, but few programming languages are designed to roll dice.\nOne such language is [Troll][troll].\n\n[troll]: https://di.ku.dk/Ansatte/?pure=da%2Fpublications%2Ftroll-a-language-for-specifying-dicerolls(84a45ff0-068b-11df-825d-000ea68e967b)%2Fexport.html\n~~~~\n\n[dnd]: https://en.wikipedia.org/wiki/Dungeons_%26_Dragons\n"
  },
  {
    "path": "exercises/practice/dnd-character/.docs/introduction.md",
    "content": "# Introduction\n\nAfter weeks of anticipation, you and your friends get together for your very first game of [Dungeons & Dragons][dnd] (D&D).\nSince this is the first session of the game, each player has to generate a character to play with.\nThe character's abilities are determined by rolling 6-sided dice, but where _are_ the dice?\nWith a shock, you realize that your friends are waiting for _you_ to produce the dice; after all it was your idea to play D&D!\nPanicking, you realize you forgot to bring the dice, which would mean no D&D game.\nAs you have some basic coding skills, you quickly come up with a solution: you'll write a program to simulate dice rolls.\n\n[dnd]: https://en.wikipedia.org/wiki/Dungeons_%26_Dragons\n"
  },
  {
    "path": "exercises/practice/dnd-character/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/DndCharacter.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/DndCharacterTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/DndCharacter.kt\"\n    ]\n  },\n  \"blurb\": \"Randomly generate Dungeons & Dragons characters.\",\n  \"source\": \"Simon Shine, Erik Schierboom\",\n  \"source_url\": \"https://github.com/exercism/problem-specifications/issues/616#issuecomment-437358945\"\n}\n"
  },
  {
    "path": "exercises/practice/dnd-character/.meta/src/reference/kotlin/DndCharacter.kt",
    "content": "import java.lang.Math.floorDiv\nimport kotlin.random.Random\n\nclass DndCharacter {\n\n    val strength: Int = ability()\n    val dexterity: Int = ability()\n    val constitution: Int = ability()\n    val intelligence: Int = ability()\n    val wisdom: Int = ability()\n    val charisma: Int = ability()\n    val hitpoints: Int = 10 + modifier(constitution)\n\n    companion object {\n\n        fun ability(): Int = (1 .. 4).map { Random.nextInt(1,6) }.sorted().drop(1).sum()\n\n        fun modifier(score: Int): Int = floorDiv(score - 10, 2)\n    }\n}\n"
  },
  {
    "path": "exercises/practice/dnd-character/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# ability modifier for score 3 is -4\n\"1e9ae1dc-35bd-43ba-aa08-e4b94c20fa37\" = true\n\n# ability modifier for score 4 is -3\n\"cc9bb24e-56b8-4e9e-989d-a0d1a29ebb9c\" = true\n\n# ability modifier for score 5 is -3\n\"5b519fcd-6946-41ee-91fe-34b4f9808326\" = true\n\n# ability modifier for score 6 is -2\n\"dc2913bd-6d7a-402e-b1e2-6d568b1cbe21\" = true\n\n# ability modifier for score 7 is -2\n\"099440f5-0d66-4b1a-8a10-8f3a03cc499f\" = true\n\n# ability modifier for score 8 is -1\n\"cfda6e5c-3489-42f0-b22b-4acb47084df0\" = true\n\n# ability modifier for score 9 is -1\n\"c70f0507-fa7e-4228-8463-858bfbba1754\" = true\n\n# ability modifier for score 10 is 0\n\"6f4e6c88-1cd9-46a0-92b8-db4a99b372f7\" = true\n\n# ability modifier for score 11 is 0\n\"e00d9e5c-63c8-413f-879d-cd9be9697097\" = true\n\n# ability modifier for score 12 is +1\n\"eea06f3c-8de0-45e7-9d9d-b8cab4179715\" = true\n\n# ability modifier for score 13 is +1\n\"9c51f6be-db72-4af7-92ac-b293a02c0dcd\" = true\n\n# ability modifier for score 14 is +2\n\"94053a5d-53b6-4efc-b669-a8b5098f7762\" = true\n\n# ability modifier for score 15 is +2\n\"8c33e7ca-3f9f-4820-8ab3-65f2c9e2f0e2\" = true\n\n# ability modifier for score 16 is +3\n\"c3ec871e-1791-44d0-b3cc-77e5fb4cd33d\" = true\n\n# ability modifier for score 17 is +3\n\"3d053cee-2888-4616-b9fd-602a3b1efff4\" = true\n\n# ability modifier for score 18 is +4\n\"bafd997a-e852-4e56-9f65-14b60261faee\" = true\n\n# random ability is within range\n\"4f28f19c-2e47-4453-a46a-c0d365259c14\" = true\n\n# random character is valid\n\"385d7e72-864f-4e88-8279-81a7d75b04ad\" = true\n\n# each ability is only calculated once\n\"2ca77b9b-c099-46c3-a02c-0d0f68ffa0fe\" = true\n"
  },
  {
    "path": "exercises/practice/dnd-character/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/dnd-character/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/dnd-character/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/dnd-character/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/dnd-character/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/dnd-character/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/dnd-character/src/main/kotlin/DndCharacter.kt",
    "content": "class DndCharacter {\n\n    val strength: Int = TODO(\"Initialize value to complete the task\")\n    val dexterity: Int = TODO(\"Initialize value to complete the task\")\n    val constitution: Int = TODO(\"Initialize value to complete the task\")\n    val intelligence: Int = TODO(\"Initialize value to complete the task\")\n    val wisdom: Int = TODO(\"Initialize value to complete the task\")\n    val charisma: Int = TODO(\"Initialize value to complete the task\")\n    val hitpoints: Int = TODO(\"Initialize value to complete the task\")\n\n    companion object {\n\n        fun ability(): Int {\n            TODO(\"Implement the function to complete the task\")\n        }\n\n        fun modifier(score: Int): Int {\n            TODO(\"Implement the function to complete the task\")\n        }\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/dnd-character/src/test/kotlin/DndCharacterTest.kt",
    "content": "import kotlin.test.Ignore\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\nimport kotlin.test.assertTrue\n\nclass DndCharacterTest {\n\n    @Test\n    fun `ability modifier for score 3 is n4`() = assertEquals(-4, DndCharacter.modifier(3))\n\n    @Ignore\n    @Test\n    fun `ability modifier for score 4 is n3`() = assertEquals(-3, DndCharacter.modifier(4))\n\n    @Ignore\n    @Test\n    fun `ability modifier for score 5 is n3`() = assertEquals(-3, DndCharacter.modifier(5))\n\n    @Ignore\n    @Test\n    fun `ability modifier for score 6 is n2`() = assertEquals(-2, DndCharacter.modifier(6))\n\n    @Ignore\n    @Test\n    fun `ability modifier for score 7 is n2`() = assertEquals(-2, DndCharacter.modifier(7))\n\n    @Ignore\n    @Test\n    fun `ability modifier for score 8 is n1`() = assertEquals(-1, DndCharacter.modifier(8))\n\n    @Ignore\n    @Test\n    fun `ability modifier for score 9 is n1`() = assertEquals(-1, DndCharacter.modifier(9))\n\n    @Ignore\n    @Test\n    fun `ability modifier for score 10 is 0`() = assertEquals(0, DndCharacter.modifier(10))\n\n    @Ignore\n    @Test\n    fun `ability modifier for score 11 is 0`() = assertEquals(0, DndCharacter.modifier(11))\n\n    @Ignore\n    @Test\n    fun `ability modifier for score 12 is 1`() = assertEquals(1, DndCharacter.modifier(12))\n\n    @Ignore\n    @Test\n    fun `ability modifier for score 13 is 1`() = assertEquals(1, DndCharacter.modifier(13))\n\n    @Ignore\n    @Test\n    fun `ability modifier for score 14 is 2`() = assertEquals(2, DndCharacter.modifier(14))\n\n    @Ignore\n    @Test\n    fun `ability modifier for score 15 is 2`() = assertEquals(2, DndCharacter.modifier(15))\n\n    @Ignore\n    @Test\n    fun `ability modifier for score 16 is 3`() = assertEquals(3, DndCharacter.modifier(16))\n\n    @Ignore\n    @Test\n    fun `ability modifier for score 17 is 3`() = assertEquals(3, DndCharacter.modifier(17))\n\n    @Ignore\n    @Test\n    fun `ability modifier for score 18 is 4`() = assertEquals(4, DndCharacter.modifier(18))\n\n    @Ignore\n    @Test\n    fun `random ability is within range`() {\n        val score = DndCharacter.ability()\n        assertTrue(score in (3..18))\n    }\n\n    @Ignore\n    @Test\n    fun `random character is valid`() {\n        with (DndCharacter()) {\n            assertTrue(strength in (3..18))\n            assertTrue(dexterity in (3..18))\n            assertTrue(constitution in (3..18))\n            assertTrue(intelligence in (3..18))\n            assertTrue(wisdom in (3..18))\n            assertTrue(charisma in (3..18))\n            assertEquals(10 + DndCharacter.modifier(constitution), hitpoints)\n        }\n    }\n\n    @Ignore\n    @Test\n    fun `each ability is only calculated once`() {\n        val char = DndCharacter()\n        assertTrue(char.strength == char.strength)\n    }\n}\n"
  },
  {
    "path": "exercises/practice/dominoes/.docs/instructions.md",
    "content": "# Instructions\n\nMake a chain of dominoes.\n\nCompute a way to order a given set of domino stones so that they form a correct domino chain.\nIn the chain, the dots on one half of a stone must match the dots on the neighboring half of an adjacent stone.\nAdditionally, the dots on the halves of the stones without neighbors (the first and last stone) must match each other.\n\nFor example given the stones `[2|1]`, `[2|3]` and `[1|3]` you should compute something\nlike `[1|2] [2|3] [3|1]` or `[3|2] [2|1] [1|3]` or `[1|3] [3|2] [2|1]` etc, where the first and last numbers are the same.\n\nFor stones `[1|2]`, `[4|1]` and `[2|3]` the resulting chain is not valid: `[4|1] [1|2] [2|3]`'s first and last numbers are not the same.\n4 != 3\n\nSome test cases may use duplicate stones in a chain solution, assume that multiple Domino sets are being used.\n"
  },
  {
    "path": "exercises/practice/dominoes/.docs/introduction.md",
    "content": "# Introduction\n\nIn Toyland, the trains are always busy delivering treasures across the city, from shiny marbles to rare building blocks.\nThe tracks they run on are made of colorful domino-shaped pieces, each marked with two numbers.\nFor the trains to move, the dominoes must form a perfect chain where the numbers match.\n\nToday, an urgent delivery of rare toys is on hold.\nYou've been handed a set of track pieces to inspect.\nIf they can form a continuous chain, the train will be on its way, bringing smiles across Toyland.\nIf not, the set will be discarded, and another will be tried.\n\nThe toys are counting on you to solve this puzzle.\nWill the dominoes connect the tracks and send the train rolling, or will the set be left behind?\n"
  },
  {
    "path": "exercises/practice/dominoes/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Dominoes.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/DominoesTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Dominoes.kt\"\n    ]\n  },\n  \"blurb\": \"Make a chain of dominoes.\"\n}\n"
  },
  {
    "path": "exercises/practice/dominoes/.meta/src/reference/kotlin/Dominoes.kt",
    "content": "import java.util.*\n\nclass ChainNotFoundException(msg: String) : RuntimeException(msg)\n\ndata class Domino(val left: Int, val right: Int)\n\nobject Dominoes {\n\n    fun formChain(vararg inputDominoes: Domino): List<Domino> = formChain(inputDominoes.toList())\n\n    fun formChain(inputDominoes: List<Domino>): List<Domino> {\n        if (inputDominoes.isEmpty()) {\n            return emptyList()\n        }\n        return formPartialChain(ArrayList(), inputDominoes)\n    }\n\n    private fun isValidChain(chain: ArrayList<Domino>): Boolean {\n        return isValidPartialChain(chain) && chain.first().left == chain.last().right\n    }\n\n    private fun isValidPartialChain(chain: ArrayList<Domino>): Boolean {\n        for (i in 0 until chain.size - 1) {\n            if (chain[i].right != chain[i + 1].left) {\n                return false\n            }\n        }\n        return true\n    }\n\n    private fun formPartialChain(current: ArrayList<Domino>, remaining: List<Domino>): ArrayList<Domino> {\n        if (remaining.isEmpty()) {\n            if (isValidChain(current)) {\n                return current\n            } else {\n                throw ChainNotFoundException(\"No domino chain found.\")\n            }\n        }\n        remaining.indices.forEach { i ->\n            val newRemaining = ArrayList(remaining)\n            newRemaining.removeAt(i)\n\n            val newChainA = ArrayList(current)\n            newChainA.add(remaining[i])\n\n            val newChainB = ArrayList(current)\n            newChainB.add(Domino(remaining[i].right, remaining[i].left))\n\n            if (isValidPartialChain(newChainA)) {\n                try {\n                    return formPartialChain(newChainA, newRemaining)\n                } catch (e: ChainNotFoundException) {\n                    //This path does not have a valid chain\n                }\n            }\n            if (isValidPartialChain(newChainB)) {\n                try {\n                    return formPartialChain(newChainB, newRemaining)\n                } catch (e: ChainNotFoundException) {\n                    //This path doesn't have a valid chain\n                }\n            }\n        }\n\n        throw ChainNotFoundException(\"No domino chain found.\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/dominoes/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# empty input = empty output\n\"31a673f2-5e54-49fe-bd79-1c1dae476c9c\" = true\n\n# singleton input = singleton output\n\"4f99b933-367b-404b-8c6d-36d5923ee476\" = true\n\n# singleton that can't be chained\n\"91122d10-5ec7-47cb-b759-033756375869\" = true\n\n# three elements\n\"be8bc26b-fd3d-440b-8e9f-d698a0623be3\" = true\n\n# can reverse dominoes\n\"99e615c6-c059-401c-9e87-ad7af11fea5c\" = true\n\n# can't be chained\n\"51f0c291-5d43-40c5-b316-0429069528c9\" = true\n\n# disconnected - simple\n\"9a75e078-a025-4c23-8c3a-238553657f39\" = true\n\n# disconnected - double loop\n\"0da0c7fe-d492-445d-b9ef-1f111f07a301\" = true\n\n# disconnected - single isolated\n\"b6087ff0-f555-4ea0-a71c-f9d707c5994a\" = true\n\n# need backtrack\n\"2174fbdc-8b48-4bac-9914-8090d06ef978\" = true\n\n# separate loops\n\"167bb480-dfd1-4318-a20d-4f90adb4a09f\" = true\n\n# nine elements\n\"cd061538-6046-45a7-ace9-6708fe8f6504\" = true\n"
  },
  {
    "path": "exercises/practice/dominoes/.meta/version",
    "content": "2.1.0\n"
  },
  {
    "path": "exercises/practice/dominoes/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/dominoes/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/dominoes/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/dominoes/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/dominoes/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/dominoes/src/main/kotlin/Dominoes.kt",
    "content": "class ChainNotFoundException(msg: String) : RuntimeException(msg)\n\ndata class Domino(val left: Int, val right: Int)\n\nobject Dominoes {\n\n    fun formChain(inputDominoes: List<Domino>): List<Domino> {\n        TODO(\"Implement this to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/dominoes/src/test/kotlin/DominoesTest.kt",
    "content": "import kotlin.test.Ignore\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\n\nclass DominoesTest {\n\n    @Test\n    fun `empty input = empty output`() = Dominoes.formChain().should { haveSize(0) }\n\n    @Ignore\n    @Test\n    fun `singleton input = singleton output`() {\n        val input = listOf(Domino(1, 1))\n        Dominoes.formChain(input).should { beValidDominoes(input) }\n    }\n\n    @Ignore\n    @Test(ChainNotFoundException::class)\n    fun `singleton can't be chained`() {\n        Dominoes.formChain(Domino(1, 2))\n    }\n\n    @Ignore\n    @Test\n    fun `three elements`() {\n        val input = listOf(Domino(1, 2), Domino(3, 1), Domino(2, 3))\n        Dominoes.formChain(input).should { beValidDominoes(input) }\n    }\n\n    @Ignore\n    @Test\n    fun `can reverse dominoes`() {\n        val input = listOf(Domino(1, 2), Domino(1, 3), Domino(2, 3))\n        Dominoes.formChain(input).should { beValidDominoes(input) }\n    }\n\n    @Ignore\n    @Test(expected = ChainNotFoundException::class)\n    fun `can't be chained`() {\n        Dominoes.formChain(Domino(1, 2), Domino(4, 1), Domino(2, 3))\n    }\n\n    @Ignore\n    @Test(expected = ChainNotFoundException::class)\n    fun `disconnected - simple`() {\n        Dominoes.formChain(Domino(1, 1), Domino(2, 2))\n    }\n\n    @Ignore\n    @Test(expected = ChainNotFoundException::class)\n    fun `disconnected - double loop`() {\n        Dominoes.formChain(Domino(1, 2), Domino(2, 1), Domino(3, 4), Domino(4, 3))\n    }\n\n    @Ignore\n    @Test(expected = ChainNotFoundException::class)\n    fun `disconnected - single isolated`() {\n        Dominoes.formChain(Domino(1, 2), Domino(2, 3), Domino(3, 1), Domino(4, 4))\n    }\n\n    @Ignore\n    @Test\n    fun `need backtrack`() {\n        val input = listOf(\n                Domino(1, 2),\n                Domino(2, 3),\n                Domino(3, 1),\n                Domino(2, 4),\n                Domino(4, 2))\n        Dominoes.formChain(input).should { beValidDominoes(input) }\n    }\n\n    @Ignore\n    @Test\n    fun `separate loops`() {\n        val input = listOf(\n                Domino(1, 2),\n                Domino(2, 3),\n                Domino(3, 1),\n                Domino(1, 1),\n                Domino(2, 2),\n                Domino(3, 3))\n        Dominoes.formChain(input).should { beValidDominoes(input) }\n    }\n\n    @Ignore\n    @Test\n    fun `nine elements`() {\n        val input = listOf(\n                Domino(1, 2),\n                Domino(5, 3),\n                Domino(3, 1),\n                Domino(1, 2),\n                Domino(2, 4),\n                Domino(1, 6),\n                Domino(2, 3),\n                Domino(3, 4),\n                Domino(5, 6))\n        Dominoes.formChain(input).should { beValidDominoes(input) }\n    }\n\n    private fun List<Domino>.should(what: DominoListAsserter.() -> Unit) = what(DominoListAsserter(this))\n\n    private class DominoListAsserter(private val outputDominoes: List<Domino>) {\n\n        fun haveSize(n: Int) = assertEquals(n, outputDominoes.size)\n\n        fun beValidDominoes(inputDominoes: List<Domino>) {\n            haveSameDominoesAs(inputDominoes)\n            haveMatchingEnds()\n            haveConsecutiveDominoes()\n        }\n\n        private fun haveSameDominoesAs(inputDominoes: List<Domino>) {\n            val errorMessage = \"The number of dominoes in the input list (${inputDominoes.size}) needs to match the number of dominoes in the output chain (${outputDominoes.size})\"\n            assertEquals(inputDominoes.size, outputDominoes.size, errorMessage)\n            inputDominoes.forEach { domino ->\n                val inputFrequency: Int = dominoFrequency(inputDominoes, domino)\n                val outputFrequency: Int = dominoFrequency(outputDominoes, domino)\n                val frequencyErrorMessage = \"The frequency of domino (${domino.left}, ${domino.right}) in the input is ($inputFrequency), but ($outputFrequency) in the output.\"\n                assertEquals(inputFrequency, outputFrequency, frequencyErrorMessage)\n            }\n        }\n\n        private fun haveMatchingEnds() {\n            val leftValueOfFirstDomino = outputDominoes.first().left\n            val rightValueOfLastDomino = outputDominoes.last().right\n            val errorMessage = \"The left value of the first domino ($leftValueOfFirstDomino) needs to match the right value of the last domino ($rightValueOfLastDomino).\"\n            assertEquals(leftValueOfFirstDomino, rightValueOfLastDomino, errorMessage)\n        }\n\n        private fun haveConsecutiveDominoes() {\n            (0 until outputDominoes.size - 1).forEach { i ->\n                val rightValueOfIthDomino = outputDominoes[i].right\n                val leftValueOfNextDomino = outputDominoes[i + 1].left\n                val errorMessage = \"The right value of domino number $i ($rightValueOfIthDomino) needs to match the left value of domino number ${i + 1} ($leftValueOfNextDomino).\"\n                assertEquals(outputDominoes[i].right, outputDominoes[i + 1].left, errorMessage)\n            }\n        }\n\n        private fun dominoFrequency(list: List<Domino>, d: Domino) =\n                list.count {\n                    (it.left == d.left && it.right == d.right) || (it.left == d.right && it.right == d.left)\n                }\n\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/eliuds-eggs/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to count the number of 1 bits in the binary representation of a number.\n\n## Restrictions\n\nKeep your hands off that bit-count functionality provided by your standard library!\nSolve this one yourself using other basic tools instead.\n"
  },
  {
    "path": "exercises/practice/eliuds-eggs/.docs/introduction.md",
    "content": "# Introduction\n\nYour friend Eliud inherited a farm from her grandma Tigist.\nHer granny was an inventor and had a tendency to build things in an overly complicated manner.\nThe chicken coop has a digital display showing an encoded number representing the positions of all eggs that could be picked up.\n\nEliud is asking you to write a program that shows the actual number of eggs in the coop.\n\nThe position information encoding is calculated as follows:\n\n1. Scan the potential egg-laying spots and mark down a `1` for an existing egg or a `0` for an empty spot.\n2. Convert the number from binary to decimal.\n3. Show the result on the display.\n\n## Example 1\n\n![Seven individual nest boxes arranged in a row whose first, third, fourth and seventh nests each have a single egg.](https://assets.exercism.org/images/exercises/eliuds-eggs/example-1-coop.svg)\n\n```text\n _ _ _ _ _ _ _\n|E| |E|E| | |E|\n```\n\n### Resulting Binary\n\n![1011001](https://assets.exercism.org/images/exercises/eliuds-eggs/example-1-binary.svg)\n\n```text\n _ _ _ _ _ _ _\n|1|0|1|1|0|0|1|\n```\n\n### Decimal number on the display\n\n89\n\n### Actual eggs in the coop\n\n4\n\n## Example 2\n\n![Seven individual nest boxes arranged in a row where only the fourth nest has an egg.](https://assets.exercism.org/images/exercises/eliuds-eggs/example-2-coop.svg)\n\n```text\n _ _ _ _ _ _ _\n| | | |E| | | |\n```\n\n### Resulting Binary\n\n![0001000](https://assets.exercism.org/images/exercises/eliuds-eggs/example-2-binary.svg)\n\n```text\n _ _ _ _ _ _ _\n|0|0|0|1|0|0|0|\n```\n\n### Decimal number on the display\n\n16\n\n### Actual eggs in the coop\n\n1\n"
  },
  {
    "path": "exercises/practice/eliuds-eggs/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"BNAndras\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/EliudsEggs.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/EliudsEggsTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/EliudsEggs.kt\"\n    ]\n  },\n  \"blurb\": \"Help Eliud count the number of eggs in her chicken coop by counting the number of 1 bits in a binary representation.\",\n  \"source\": \"Christian Willner, Eric Willigers\",\n  \"source_url\": \"https://forum.exercism.org/t/new-exercise-suggestion-pop-count/7632/5\"\n}\n"
  },
  {
    "path": "exercises/practice/eliuds-eggs/.meta/src/reference/kotlin/EliudsEggs.kt",
    "content": "object EliudsEggs {\n\n    fun eggCount(number: Int): Int{\n        return number.countOneBits()\n    }\n}\n"
  },
  {
    "path": "exercises/practice/eliuds-eggs/.meta/tests.toml",
    "content": "# This is an auto-generated file.\n#\n# Regenerating this file via `configlet sync` will:\n# - Recreate every `description` key/value pair\n# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications\n# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)\n# - Preserve any other key/value pair\n#\n# As user-added comments (using the # character) will be removed when this file\n# is regenerated, comments can be added via a `comment` key.\n\n[559e789d-07d1-4422-9004-3b699f83bca3]\ndescription = \"0 eggs\"\n\n[97223282-f71e-490c-92f0-b3ec9e275aba]\ndescription = \"1 egg\"\n\n[1f8fd18f-26e9-4144-9a0e-57cdfc4f4ff5]\ndescription = \"4 eggs\"\n\n[0c18be92-a498-4ef2-bcbb-28ac4b06cb81]\ndescription = \"13 eggs\"\n"
  },
  {
    "path": "exercises/practice/eliuds-eggs/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/eliuds-eggs/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/eliuds-eggs/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/eliuds-eggs/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/eliuds-eggs/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/eliuds-eggs/src/main/kotlin/EliudsEggs.kt",
    "content": "object EliudsEggs {\n\n    fun eggCount(number: Int): Int{\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/eliuds-eggs/src/test/kotlin/EliudsEggsTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass EliudsEggsTest {\n\n    @Test\n    fun `0 eggs`() = assertEquals(0, EliudsEggs.eggCount(0))\n\n    @Ignore\n    @Test\n    fun `1 egg`() = assertEquals(1, EliudsEggs.eggCount(16))\n\n    @Ignore\n    @Test\n    fun `4 eggs`() = assertEquals(4, EliudsEggs.eggCount(89))\n\n    @Ignore\n    @Test\n    fun `13 eggs`() = assertEquals(13, EliudsEggs.eggCount(2_000_000_000))\n}\n"
  },
  {
    "path": "exercises/practice/etl/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to change the data format of letters and their point values in the game.\n\nCurrently, letters are stored in groups based on their score, in a one-to-many mapping.\n\n- 1 point: \"A\", \"E\", \"I\", \"O\", \"U\", \"L\", \"N\", \"R\", \"S\", \"T\",\n- 2 points: \"D\", \"G\",\n- 3 points: \"B\", \"C\", \"M\", \"P\",\n- 4 points: \"F\", \"H\", \"V\", \"W\", \"Y\",\n- 5 points: \"K\",\n- 8 points: \"J\", \"X\",\n- 10 points: \"Q\", \"Z\",\n\nThis needs to be changed to store each individual letter with its score in a one-to-one mapping.\n\n- \"a\" is worth 1 point.\n- \"b\" is worth 3 points.\n- \"c\" is worth 3 points.\n- \"d\" is worth 2 points.\n- etc.\n\nAs part of this change, the team has also decided to change the letters to be lower-case rather than upper-case.\n\n~~~~exercism/note\nIf you want to look at how the data was previously structured and how it needs to change, take a look at the examples in the test suite.\n~~~~\n"
  },
  {
    "path": "exercises/practice/etl/.docs/introduction.md",
    "content": "# Introduction\n\nYou work for a company that makes an online multiplayer game called Lexiconia.\n\nTo play the game, each player is given 13 letters, which they must rearrange to create words.\nDifferent letters have different point values, since it's easier to create words with some letters than others.\n\nThe game was originally launched in English, but it is very popular, and now the company wants to expand to other languages as well.\n\nDifferent languages need to support different point values for letters.\nThe point values are determined by how often letters are used, compared to other letters in that language.\n\nFor example, the letter 'C' is quite common in English, and is only worth 3 points.\nBut in Norwegian it's a very rare letter, and is worth 10 points.\n\nTo make it easier to add new languages, your team needs to change the way letters and their point values are stored in the game.\n"
  },
  {
    "path": "exercises/practice/etl/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"kytrinyx\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/ETL.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ETLTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/ETL.kt\"\n    ]\n  },\n  \"blurb\": \"Change the data format for scoring a game to more easily add other languages.\",\n  \"source\": \"Based on an exercise by the JumpstartLab team for students at The Turing School of Software and Design.\",\n  \"source_url\": \"https://turing.edu\"\n}\n"
  },
  {
    "path": "exercises/practice/etl/.meta/src/reference/kotlin/ETL.kt",
    "content": "object ETL {\n\n    fun transform(old: Map<Int, Collection<Char>>): Map<Char, Int> {\n        return old.flatMap { mapEntry ->\n            mapEntry.value.map { word ->\n                Pair(word.lowercaseChar(), mapEntry.key)\n            }\n        }.toMap()\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/etl/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# single letter\n\"78a7a9f9-4490-4a47-8ee9-5a38bb47d28f\" = true\n\n# single score with multiple letters\n\"60dbd000-451d-44c7-bdbb-97c73ac1f497\" = true\n\n# multiple scores with multiple letters\n\"f5c5de0c-301f-4fdd-a0e5-df97d4214f54\" = true\n\n# multiple scores with differing numbers of letters\n\"5db8ea89-ecb4-4dcd-902f-2b418cc87b9d\" = true\n"
  },
  {
    "path": "exercises/practice/etl/.meta/version",
    "content": "2.0.1\n"
  },
  {
    "path": "exercises/practice/etl/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/etl/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/etl/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/etl/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/etl/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/etl/src/main/kotlin/ETL.kt",
    "content": "object ETL {\n    fun transform(source: Map<Int, Collection<Char>>): Map<Char, Int> {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/etl/src/test/kotlin/ETLTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass ETLTest {\n\n    @Test\n    fun `single letter`() = assertTransformedEquals(\n            mapOf(\n                    1 to listOf('A')),\n            mapOf(\n                    'a' to 1))\n\n    @Ignore\n    @Test\n    fun `single score with multiple letters`() = assertTransformedEquals(\n            mapOf(\n                    1 to listOf('A', 'E', 'I', 'O', 'U')),\n            mapOf(\n                    'a' to 1, 'e' to 1, 'i' to 1, 'o' to 1, 'u' to 1))\n\n    @Ignore\n    @Test\n    fun `multiple scores with multiple letters`() = assertTransformedEquals(\n            mapOf(\n                    1 to listOf('A', 'E'), 2 to listOf('D', 'G')),\n            mapOf(\n                    'a' to 1, 'd' to 2, 'e' to 1, 'g' to 2))\n\n    @Ignore\n    @Test\n    fun `multiple scores with differing numbers of letters`() =\n            assertTransformedEquals(\n                    mapOf(\n                            1 to listOf('A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'),\n                            2 to listOf('D', 'G'),\n                            3 to listOf('B', 'C', 'M', 'P'),\n                            4 to listOf('F', 'H', 'V', 'W', 'Y'),\n                            5 to listOf('K'),\n                            8 to listOf('J', 'X'),\n                            10 to listOf('Q', 'Z')),\n                    mapOf(\n                            'a' to 1, 'b' to 3, 'c' to 3, 'd' to 2, 'e' to 1,\n                            'f' to 4, 'g' to 2, 'h' to 4, 'i' to 1, 'j' to 8,\n                            'k' to 5, 'l' to 1, 'm' to 3, 'n' to 1, 'o' to 1,\n                            'p' to 3, 'q' to 10, 'r' to 1, 's' to 1, 't' to 1,\n                            'u' to 1, 'v' to 4, 'w' to 4, 'x' to 8, 'y' to 4,\n                            'z' to 10))\n\n}\n\nprivate fun assertTransformedEquals(input: Map<Int, List<Char>>, expectation: Map<Char, Int>) =\n        assertEquals(expectation, ETL.transform(input))\n\n"
  },
  {
    "path": "exercises/practice/flatten-array/.docs/instructions.md",
    "content": "# Instructions\n\nTake a nested array of any depth and return a fully flattened array.\n\nNote that some language tracks may include null-like values in the input array, and the way these values are represented varies by track.\nSuch values should be excluded from the flattened array.\n\nAdditionally, the input may be of a different data type and contain different types, depending on the track.\n\nCheck the test suite for details.\n\n## Example\n\ninput: `[1, [2, 6, null], [[null, [4]], 5]]`\n\noutput: `[1, 2, 6, 4, 5]`\n"
  },
  {
    "path": "exercises/practice/flatten-array/.docs/introduction.md",
    "content": "# Introduction\n\nA shipment of emergency supplies has arrived, but there's a problem.\nTo protect from damage, the items — flashlights, first-aid kits, blankets — are packed inside boxes, and some of those boxes are nested several layers deep inside other boxes!\n\nTo be prepared for an emergency, everything must be easily accessible in one box.\nCan you unpack all the supplies and place them into a single box, so they're ready when needed most?\n"
  },
  {
    "path": "exercises/practice/flatten-array/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Flattener.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/FlattenerTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Flattener.kt\"\n    ]\n  },\n  \"blurb\": \"Take a nested list and return a single list with all values except nil/null.\",\n  \"source\": \"Interview Question\",\n  \"source_url\": \"https://reference.wolfram.com/language/ref/Flatten.html\"\n}\n"
  },
  {
    "path": "exercises/practice/flatten-array/.meta/src/reference/kotlin/Flattener.kt",
    "content": "object Flattener {\n\n    fun flatten(unflattened: Collection<Any?>): List<Any> {\n        return unflattened.filterNotNull().fold(mutableListOf()) { accum, element -> accum.addFlattened(element); accum }\n    }\n\n    fun MutableCollection<Any>.addFlattened(item: Any) = if (item is Collection<*>) this.addAll(flatten(item)) else this.add(item)\n\n}\n"
  },
  {
    "path": "exercises/practice/flatten-array/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# no nesting\n\"d268b919-963c-442d-9f07-82b93f1b518c\" = true\n\n# flattens array with just integers present\n\"c84440cc-bb3a-48a6-862c-94cf23f2815d\" = true\n\n# 5 level nesting\n\"d3d99d39-6be5-44f5-a31d-6037d92ba34f\" = true\n\n# 6 level nesting\n\"d572bdba-c127-43ed-bdcd-6222ac83d9f7\" = true\n\n# 6 level nest list with null values\n\"ef1d4790-1b1e-4939-a179-51ace0829dbd\" = true\n\n# all values in nested list are null\n\"85721643-705a-4150-93ab-7ae398e2942d\" = true\n"
  },
  {
    "path": "exercises/practice/flatten-array/.meta/version",
    "content": "1.2.0\n"
  },
  {
    "path": "exercises/practice/flatten-array/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/flatten-array/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/flatten-array/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/flatten-array/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/flatten-array/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/flatten-array/src/main/kotlin/Flattener.kt",
    "content": "object Flattener {\n    fun flatten(source: Collection<Any?>): List<Any> {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/flatten-array/src/test/kotlin/FlattenerTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass FlattenerTest {\n\n    @Test\n    fun flatListIsUnchanged() {\n        val flatList = listOf(0, 1, 2)\n        assertEquals(listOf(0, 1, 2), Flattener.flatten(flatList))\n    }\n\n    @Ignore\n    @Test\n    fun flattens2LevelNestedList() {\n        val nestedList = listOf(1, listOf(2, 3, 4, 5, 6, 7), 8)\n        assertEquals(listOf(1, 2, 3, 4, 5, 6, 7, 8), Flattener.flatten(nestedList))\n    }\n\n    @Ignore\n    @Test\n    fun flattens5LevelNestedList() {\n        val nestedList = listOf(0, 2, listOf(listOf(2, 3), 8, 100, 4, listOf(listOf(listOf(50))), -2))\n        assertEquals(listOf(0, 2, 2, 3, 8, 100, 4, 50, -2), Flattener.flatten(nestedList))\n    }\n\n    @Ignore\n    @Test\n    fun flattens6LevelNestedList() {\n        val nestedList = listOf(1, listOf(2, listOf(listOf(3)), listOf(4, listOf(listOf(5))), 6, 7), 8)\n        assertEquals(listOf(1, 2, 3, 4, 5, 6, 7, 8), Flattener.flatten(nestedList))\n    }\n\n    @Ignore\n    @Test\n    fun flattens6LevelNestedListWithNulls() {\n        val nestedList = listOf(0, 2, listOf(listOf(2, 3), 8, listOf(listOf(100)), null, listOf(listOf(null))), -2)\n        assertEquals(listOf(0, 2, 2, 3, 8, 100, -2), Flattener.flatten(nestedList))\n    }\n\n    @Ignore\n    @Test\n    fun allNullNestedListReturnsEmptyList() {\n        val nestedList = listOf(null, listOf(listOf(listOf(null))), null, null, listOf(listOf(null, null), null), null)\n        assertEquals(emptyList<Any>(), Flattener.flatten(nestedList))\n    }\n\n    @Ignore\n    @Test\n    fun flattensHeterogenousList() {\n        val nestedList = listOf(0, 2.1, listOf(listOf(true, \"flatten\"), 'a', listOf(listOf(100)), null, listOf(listOf(null))), -2)\n        assertEquals(listOf(0, 2.1, true, \"flatten\", 'a', 100, -2), Flattener.flatten(nestedList))\n    }\n}\n"
  },
  {
    "path": "exercises/practice/flower-field/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to add flower counts to empty squares in a completed Flower Field garden.\nThe garden itself is a rectangle board composed of squares that are either empty (`' '`) or a flower (`'*'`).\n\nFor each empty square, count the number of flowers adjacent to it (horizontally, vertically, diagonally).\nIf the empty square has no adjacent flowers, leave it empty.\nOtherwise replace it with the count of adjacent flowers.\n\nFor example, you may receive a 5 x 4 board like this (empty spaces are represented here with the '·' character for display on screen):\n\n```text\n·*·*·\n··*··\n··*··\n·····\n```\n\nWhich your code should transform into this:\n\n```text\n1*3*1\n13*31\n·2*2·\n·111·\n```\n"
  },
  {
    "path": "exercises/practice/flower-field/.docs/introduction.md",
    "content": "# Introduction\n\n[Flower Field][history] is a compassionate reimagining of the popular game Minesweeper.\nThe object of the game is to find all the flowers in the garden using numeric hints that indicate how many flowers are directly adjacent (horizontally, vertically, diagonally) to a square.\n\"Flower Field\" shipped in regional versions of Microsoft Windows in Italy, Germany, South Korea, Japan and Taiwan.\n\n[history]: https://web.archive.org/web/20020409051321fw_/http://rcm.usr.dsi.unimi.it/rcmweb/fnm/\n"
  },
  {
    "path": "exercises/practice/flower-field/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"BNAndras\",\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/FlowerField.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/FlowerFieldTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/FlowerField.kt\"\n    ]\n  },\n  \"blurb\": \"Mark all the flowers in a garden.\"\n}\n"
  },
  {
    "path": "exercises/practice/flower-field/.meta/src/reference/kotlin/FlowerField.kt",
    "content": "import kotlin.math.max\nimport kotlin.math.min\n\nprivate const val FLOWER_CHAR = '*'\nprivate const val SPACE_CHAR = ' '\n\ndata class FlowerFieldBoard(val flowerLocations: List<String>) {\n\n    private val numberOfRows by lazy {\n        flowerLocations.size\n    }\n\n    private val numberOfColumns by lazy {\n        if (flowerLocations.isEmpty()) 0 else flowerLocations[0].length\n    }\n\n    fun withNumbers() = (0 until numberOfRows).map { getRowWithNumbers(it) }\n\n    private fun getRowWithNumbers(rowNumber: Int) =\n            (0 until numberOfColumns)\n                    .map { columnNumber -> getCellNumber(rowNumber, columnNumber) }\n                    .joinToString(\"\")\n\n    private fun getCellNumber(rowNumber: Int, columnNumber: Int): Char {\n        // If (rowNumber, columnNumber) is a flower, we're done.\n        if (flowerLocations[rowNumber][columnNumber] == FLOWER_CHAR) {\n            return FLOWER_CHAR\n        }\n\n        val flowerCount = computeFlowerCountAround(rowNumber, columnNumber)\n\n        // If computed count is positive, add it to the annotated row. Otherwise, add a blank space.\n        return if (flowerCount > 0) Character.forDigit(flowerCount, 10) else SPACE_CHAR\n    }\n\n    private fun computeFlowerCountAround(rowNumber: Int, columnNumber: Int): Int {\n        var result = 0\n\n        // Compute row and column ranges to inspect (respecting board edges).\n        val minRowToInspect = max(rowNumber - 1, 0)\n        val maxRowToInspect = min(rowNumber + 1, numberOfRows - 1)\n        val minColToInspect = max(columnNumber - 1, 0)\n        val maxColToInspect = min(columnNumber + 1, numberOfColumns - 1)\n\n        // Count flowerss in the cells surrounding (row, col).\n        for (rowToInspect in minRowToInspect..maxRowToInspect) {\n            for (colToInspect in minColToInspect..maxColToInspect) {\n                if (flowerLocations[rowToInspect][colToInspect] == FLOWER_CHAR) {\n                    result += 1\n                }\n            }\n        }\n\n        return result\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/flower-field/.meta/tests.toml",
    "content": "# This is an auto-generated file.\n#\n# Regenerating this file via `configlet sync` will:\n# - Recreate every `description` key/value pair\n# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications\n# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)\n# - Preserve any other key/value pair\n#\n# As user-added comments (using the # character) will be removed when this file\n# is regenerated, comments can be added via a `comment` key.\n\n[237ff487-467a-47e1-9b01-8a891844f86c]\ndescription = \"no rows\"\n\n[4b4134ec-e20f-439c-a295-664c38950ba1]\ndescription = \"no columns\"\n\n[d774d054-bbad-4867-88ae-069cbd1c4f92]\ndescription = \"no flowers\"\n\n[225176a0-725e-43cd-aa13-9dced501f16e]\ndescription = \"garden full of flowers\"\n\n[3f345495-f1a5-4132-8411-74bd7ca08c49]\ndescription = \"flower surrounded by spaces\"\n\n[6cb04070-4199-4ef7-a6fa-92f68c660fca]\ndescription = \"space surrounded by flowers\"\n\n[272d2306-9f62-44fe-8ab5-6b0f43a26338]\ndescription = \"horizontal line\"\n\n[c6f0a4b2-58d0-4bf6-ad8d-ccf4144f1f8e]\ndescription = \"horizontal line, flowers at edges\"\n\n[a54e84b7-3b25-44a8-b8cf-1753c8bb4cf5]\ndescription = \"vertical line\"\n\n[b40f42f5-dec5-4abc-b167-3f08195189c1]\ndescription = \"vertical line, flowers at edges\"\n\n[58674965-7b42-4818-b930-0215062d543c]\ndescription = \"cross\"\n\n[dd9d4ca8-9e68-4f78-a677-a2a70fd7a7b8]\ndescription = \"large garden\"\n"
  },
  {
    "path": "exercises/practice/flower-field/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/flower-field/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/flower-field/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/flower-field/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/flower-field/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/flower-field/src/main/kotlin/FlowerField.kt",
    "content": "data class FlowerFieldBoard(val todo: Nothing) {\n\n    // TODO: Implement proper constructor\n\n    fun withNumbers(): List<String> {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/flower-field/src/test/kotlin/FlowerFieldTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.rules.ExpectedException\nimport kotlin.test.assertEquals\n\nclass FlowerFieldBoardTest {\n\n    /*\n     * See https://github.com/junit-team/junit4/wiki/Rules for information on JUnit Rules in general and\n     * ExpectedExceptions in particular.\n     */\n    @Rule\n    @JvmField\n    var expectedException: ExpectedException = ExpectedException.none()\n\n    @Test\n    fun testInputBoardWithNoRowsAndNoColumns() {\n        val inputBoard = emptyList<String>()\n        val expectedNumberedBoard = emptyList<String>()\n        val actualNumberedBoard = FlowerFieldBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithOneRowAndNoColumns() {\n        val inputBoard = listOf(\"\")\n        val expectedNumberedBoard = listOf(\"\")\n        val actualNumberedBoard = FlowerFieldBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithNoFlowers() {\n        val inputBoard = listOf(\n                \"   \",\n                \"   \",\n                \"   \"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \"   \",\n                \"   \",\n                \"   \"\n        )\n\n        val actualNumberedBoard = FlowerFieldBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithOnlyFlowers() {\n        val inputBoard = listOf(\n                \"***\",\n                \"***\",\n                \"***\"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \"***\",\n                \"***\",\n                \"***\"\n        )\n\n        val actualNumberedBoard = FlowerFieldBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithSingleFlowerAtCenter() {\n        val inputBoard = listOf(\n                \"   \",\n                \" * \",\n                \"   \"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \"111\",\n                \"1*1\",\n                \"111\"\n        )\n\n        val actualNumberedBoard = FlowerFieldBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithFlowersAroundPerimeter() {\n        val inputBoard = listOf(\n                \"***\",\n                \"* *\",\n                \"***\"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \"***\",\n                \"*8*\",\n                \"***\"\n        )\n\n        val actualNumberedBoard = FlowerFieldBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithSingleRowAndTwoFlowers() {\n        val inputBoard = listOf(\" * * \")\n\n        val expectedNumberedBoard = listOf(\"1*2*1\")\n\n        val actualNumberedBoard = FlowerFieldBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithSingleRowAndTwoFlowersAtEdges() {\n        val inputBoard = listOf(\"*   *\")\n\n        val expectedNumberedBoard = listOf(\"*1 1*\")\n\n        val actualNumberedBoard = FlowerFieldBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithSingleColumnAndTwoFlowers() {\n        val inputBoard = listOf(\n                \" \",\n                \"*\",\n                \" \",\n                \"*\",\n                \" \"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \"1\",\n                \"*\",\n                \"2\",\n                \"*\",\n                \"1\"\n        )\n\n        val actualNumberedBoard = FlowerFieldBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithSingleColumnAndTwoFlowersAtEdges() {\n        val inputBoard = listOf(\n                \"*\",\n                \" \",\n                \" \",\n                \" \",\n                \"*\"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \"*\",\n                \"1\",\n                \" \",\n                \"1\",\n                \"*\"\n        )\n\n        val actualNumberedBoard = FlowerFieldBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithFlowersInCross() {\n        val inputBoard = listOf(\n                \"  *  \",\n                \"  *  \",\n                \"*****\",\n                \"  *  \",\n                \"  *  \"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \" 2*2 \",\n                \"25*52\",\n                \"*****\",\n                \"25*52\",\n                \" 2*2 \"\n        )\n\n        val actualNumberedBoard = FlowerFieldBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testLargeInputBoard() {\n        val inputBoard = listOf(\n                \" *  * \",\n                \"  *   \",\n                \"    * \",\n                \"   * *\",\n                \" *  * \",\n                \"      \"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \"1*22*1\",\n                \"12*322\",\n                \" 123*2\",\n                \"112*4*\",\n                \"1*22*2\",\n                \"111111\"\n        )\n\n        val actualNumberedBoard = FlowerFieldBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/forth/.docs/instructions.md",
    "content": "# Instructions\n\nImplement an evaluator for a very simple subset of Forth.\n\n[Forth][forth]\nis a stack-based programming language.\nImplement a very basic evaluator for a small subset of Forth.\n\nYour evaluator has to support the following words:\n\n- `+`, `-`, `*`, `/` (integer arithmetic)\n- `DUP`, `DROP`, `SWAP`, `OVER` (stack manipulation)\n\nYour evaluator also has to support defining new words using the customary syntax: `: word-name definition ;`.\n\nTo keep things simple the only data type you need to support is signed integers of at least 16 bits size.\n\nYou should use the following rules for the syntax: a number is a sequence of one or more (ASCII) digits, a word is a sequence of one or more letters, digits, symbols or punctuation that is not a number.\n(Forth probably uses slightly different rules, but this is close enough.)\n\nWords are case-insensitive.\n\n[forth]: https://en.wikipedia.org/wiki/Forth_%28programming_language%29\n"
  },
  {
    "path": "exercises/practice/forth/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"lathspell\",\n    \"lihofm\",\n    \"luoken\",\n    \"mdowds\",\n    \"mikegehard\",\n    \"sjwarner-bp\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Forth.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ForthTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Forth.kt\"\n    ]\n  },\n  \"blurb\": \"Implement an evaluator for a very simple subset of Forth.\"\n}\n"
  },
  {
    "path": "exercises/practice/forth/.meta/src/reference/kotlin/Forth.kt",
    "content": "import java.util.*\n\nclass Forth {\n\n    companion object {\n        private val NUMBER_PATTERN = Regex(\"\"\"^-?\\d+$\"\"\")\n    }\n\n    private val stack: Deque<Int> = ArrayDeque()\n    private val customOps: MutableMap<String, String> = mutableMapOf()\n    private val ops = mutableMapOf(\n            \"+\" to {\n                require(stack.isNotEmpty()) { \"empty stack\" }\n                require(stack.size >= 2) { \"only one value on the stack\" }\n                stack.push(stack.pop() + stack.pop())\n            },\n            \"-\" to {\n                require(stack.isNotEmpty()) { \"empty stack\" }\n                require(stack.size >= 2) { \"only one value on the stack\" }\n                val tmp = stack.pop()\n                stack.push(stack.pop() - tmp)\n            },\n            \"*\" to {\n                require(stack.isNotEmpty()) { \"empty stack\" }\n                require(stack.size >= 2) { \"only one value on the stack\" }\n                stack.push(stack.pop() * stack.pop())\n            },\n            \"/\" to {\n                require(stack.isNotEmpty()) { \"empty stack\" }\n                require(stack.size >= 2) { \"only one value on the stack\" }\n                val tmp = stack.pop()\n                require(tmp != 0) { \"divide by zero\" }\n                stack.push(stack.pop() / tmp)\n            },\n            \"DUP\" to {\n                require(stack.isNotEmpty()) { \"empty stack\" }\n                stack.push(stack.first)\n            },\n            \"DROP\" to {\n                require(stack.isNotEmpty()) { \"empty stack\" }\n                stack.pop()\n            },\n            \"SWAP\" to {\n                require(stack.isNotEmpty()) { \"empty stack\" }\n                require(stack.size >= 2) { \"only one value on the stack\" }\n                val a = stack.pop()\n                val b = stack.pop()\n                stack.push(a)\n                stack.push(b)\n            },\n            \"OVER\" to {\n                require(stack.isNotEmpty()) { \"empty stack\" }\n                require(stack.size >= 2) { \"only one value on the stack\" }\n                stack.push(stack.elementAt(1))\n            }\n    );\n\n    fun evaluate(vararg lines: String): List<Int> {\n        lines.forEach { line ->\n            evaluateLine(line.uppercase())\n        }\n        return stack.reversed()\n    }\n\n    private fun evaluateLine(line: String) {\n        val tokens = line.split(\" \")\n\n        if (tokens.first() == \":\") {\n            val op = tokens[1]\n            val expression = tokens.subList(2, tokens.lastIndex)\n            require(!op.matches(NUMBER_PATTERN)) { \"illegal operation\" }\n            customOps[op] = expression.joinToString(\" \") { customOps.getOrDefault(it, it) }\n            return\n        }\n\n        tokens.forEach { token ->\n            when {\n                token.matches(NUMBER_PATTERN) -> stack.push(token.toInt())\n                token in customOps.keys -> evaluateLine(customOps[token]!!)\n                token in ops.keys -> ops[token]!!()\n                else -> throw IllegalArgumentException(\"undefined operation\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/forth/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# numbers just get pushed onto the stack\n\"9962203f-f00a-4a85-b404-8a8ecbcec09d\" = true\n\n# can add two numbers\n\"9e69588e-a3d8-41a3-a371-ea02206c1e6e\" = true\n\n# errors if there is nothing on the stack\n\"52336dd3-30da-4e5c-8523-bdf9a3427657\" = true\n\n# errors if there is only one value on the stack\n\"06efb9a4-817a-435e-b509-06166993c1b8\" = true\n\n# can subtract two numbers\n\"09687c99-7bbc-44af-8526-e402f997ccbf\" = true\n\n# errors if there is nothing on the stack\n\"5d63eee2-1f7d-4538-b475-e27682ab8032\" = true\n\n# errors if there is only one value on the stack\n\"b3cee1b2-9159-418a-b00d-a1bb3765c23b\" = true\n\n# can multiply two numbers\n\"5df0ceb5-922e-401f-974d-8287427dbf21\" = true\n\n# errors if there is nothing on the stack\n\"9e004339-15ac-4063-8ec1-5720f4e75046\" = true\n\n# errors if there is only one value on the stack\n\"8ba4b432-9f94-41e0-8fae-3b3712bd51b3\" = true\n\n# can divide two numbers\n\"e74c2204-b057-4cff-9aa9-31c7c97a93f5\" = true\n\n# performs integer division\n\"54f6711c-4b14-4bb0-98ad-d974a22c4620\" = true\n\n# errors if dividing by zero\n\"a5df3219-29b4-4d2f-b427-81f82f42a3f1\" = true\n\n# errors if there is nothing on the stack\n\"1d5bb6b3-6749-4e02-8a79-b5d4d334cb8a\" = true\n\n# errors if there is only one value on the stack\n\"d5547f43-c2ff-4d5c-9cb0-2a4f6684c20d\" = true\n\n# addition and subtraction\n\"ee28d729-6692-4a30-b9be-0d830c52a68c\" = true\n\n# multiplication and division\n\"40b197da-fa4b-4aca-a50b-f000d19422c1\" = true\n\n# copies a value on the stack\n\"c5758235-6eef-4bf6-ab62-c878e50b9957\" = true\n\n# copies the top value on the stack\n\"f6889006-5a40-41e7-beb3-43b09e5a22f4\" = true\n\n# errors if there is nothing on the stack\n\"40b7569c-8401-4bd4-a30d-9adf70d11bc4\" = true\n\n# removes the top value on the stack if it is the only one\n\"1971da68-1df2-4569-927a-72bf5bb7263c\" = true\n\n# removes the top value on the stack if it is not the only one\n\"8929d9f2-4a78-4e0f-90ad-be1a0f313fd9\" = true\n\n# errors if there is nothing on the stack\n\"6dd31873-6dd7-4cb8-9e90-7daa33ba045c\" = true\n\n# swaps the top two values on the stack if they are the only ones\n\"3ee68e62-f98a-4cce-9e6c-8aae6c65a4e3\" = true\n\n# swaps the top two values on the stack if they are not the only ones\n\"8ce869d5-a503-44e4-ab55-1da36816ff1c\" = true\n\n# errors if there is nothing on the stack\n\"74ba5b2a-b028-4759-9176-c5c0e7b2b154\" = true\n\n# errors if there is only one value on the stack\n\"dd52e154-5d0d-4a5c-9e5d-73eb36052bc8\" = true\n\n# copies the second element if there are only two\n\"a2654074-ba68-4f93-b014-6b12693a8b50\" = true\n\n# copies the second element if there are more than two\n\"c5b51097-741a-4da7-8736-5c93fa856339\" = true\n\n# errors if there is nothing on the stack\n\"6e1703a6-5963-4a03-abba-02e77e3181fd\" = true\n\n# errors if there is only one value on the stack\n\"ee574dc4-ef71-46f6-8c6a-b4af3a10c45f\" = true\n\n# can consist of built-in words\n\"ed45cbbf-4dbf-4901-825b-54b20dbee53b\" = true\n\n# execute in the right order\n\"2726ea44-73e4-436b-bc2b-5ff0c6aa014b\" = true\n\n# can override other user-defined words\n\"9e53c2d0-b8ef-4ad8-b2c9-a559b421eb33\" = true\n\n# can override built-in words\n\"669db3f3-5bd6-4be0-83d1-618cd6e4984b\" = true\n\n# can override built-in operators\n\"588de2f0-c56e-4c68-be0b-0bb1e603c500\" = true\n\n# can use different words with the same name\n\"ac12aaaf-26c6-4a10-8b3c-1c958fa2914c\" = true\n\n# can define word that uses word with the same name\n\"53f82ef0-2750-4ccb-ac04-5d8c1aefabb1\" = true\n\n# cannot redefine numbers\n\"35958cee-a976-4a0f-9378-f678518fa322\" = true\n\n# errors if executing a non-existent word\n\"5180f261-89dd-491e-b230-62737e09806f\" = true\n\n# DUP is case-insensitive\n\"7b83bb2e-b0e8-461f-ad3b-96ee2e111ed6\" = true\n\n# DROP is case-insensitive\n\"339ed30b-f5b4-47ff-ab1c-67591a9cd336\" = true\n\n# SWAP is case-insensitive\n\"ee1af31e-1355-4b1b-bb95-f9d0b2961b87\" = true\n\n# OVER is case-insensitive\n\"acdc3a49-14c8-4cc2-945d-11edee6408fa\" = true\n\n# user-defined words are case-insensitive\n\"5934454f-a24f-4efc-9fdd-5794e5f0c23c\" = true\n\n# definitions are case-insensitive\n\"037d4299-195f-4be7-a46d-f07ca6280a06\" = true\n"
  },
  {
    "path": "exercises/practice/forth/.meta/version",
    "content": "1.7.1\n"
  },
  {
    "path": "exercises/practice/forth/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n\n    testImplementation(kotlin(\"test\"))\n}\n\ntasks.withType<Test> {\n    useJUnitPlatform()\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/forth/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/forth/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/forth/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/forth/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/forth/src/main/kotlin/Forth.kt",
    "content": "class Forth {\n\n    fun evaluate(vararg line: String): List<Int> {\n        TODO(\"Implement this to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/forth/src/test/kotlin/ForthTest.kt",
    "content": "import org.junit.jupiter.api.Nested\nimport kotlin.test.Ignore\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\nimport kotlin.test.assertFails\n\n@Nested\nclass ForthTest {\n    @Nested\n    inner class ParsingAndNumbersTest {\n\n        @Test\n        fun `numbers just get pushed onto the stack`() =\n            assertEquals(listOf(1, 2, 3, 4, 5), Forth().evaluate(\"1 2 3 4 5\"))\n    }\n\n    @Nested\n    inner class Addition {\n\n        @Ignore\n        @Test\n        fun `can add two numbers`() = assertEquals(listOf(3), Forth().evaluate(\"1 2 +\"))\n\n        @Ignore\n        @Test\n        fun `errors if there is nothing on the stack`() {\n            val ex = assertFails { Forth().evaluate(\"+\") }\n            assertEquals(\"empty stack\", ex.message)\n        }\n\n        @Ignore\n        @Test\n        fun `errors if there is only one value on the stack`() {\n            val ex = assertFails { Forth().evaluate(\"1 +\") }\n            assertEquals(\"only one value on the stack\", ex.message)\n        }\n    }\n\n    @Nested\n    inner class Subtraction {\n\n        @Ignore\n        @Test\n        fun `can subtract two numbers`() = assertEquals(listOf(-1), Forth().evaluate(\"3 4 -\"))\n\n        @Ignore\n        @Test\n        fun `errors if there is nothing on the stack`() {\n            val ex = assertFails { Forth().evaluate(\"-\") }\n            assertEquals(\"empty stack\", ex.message)\n        }\n\n        @Ignore\n        @Test\n        fun `errors if there is only one value on the stack`() {\n            val ex = assertFails { Forth().evaluate(\"1 -\") }\n            assertEquals(\"only one value on the stack\", ex.message)\n        }\n    }\n\n    @Nested\n    inner class Multiplication {\n\n        @Ignore\n        @Test\n        fun `can multiply two numbers`() =\n            assertEquals(listOf(8), Forth().evaluate(\"2 4 *\"))\n\n        @Ignore\n        @Test\n        fun `errors if there is nothing on the stack`() {\n            val ex = assertFails {\n                Forth().evaluate(\"*\")\n            }\n            assertEquals(\"empty stack\", ex.message)\n        }\n\n        @Ignore\n        @Test\n        fun `errors if there is only one value on the stack`() {\n            val ex = assertFails {\n                Forth().evaluate(\"1 *\")\n            }\n            assertEquals(\"only one value on the stack\", ex.message)\n        }\n    }\n\n    @Nested\n    inner class Division {\n\n        @Ignore\n        @Test\n        fun `can divide two numbers`() =\n            assertEquals(listOf(4), Forth().evaluate(\"12 3 /\"))\n\n        @Ignore\n        @Test\n        fun `performs integer division`() =\n            assertEquals(listOf(2), Forth().evaluate(\"8 3 /\"))\n\n        @Ignore\n        @Test\n        fun `errors if dividing by zero`() {\n            val ex = assertFails { Forth().evaluate(\"4 0 /\") }\n            assertEquals(\"divide by zero\", ex.message)\n        }\n\n        @Ignore\n        @Test\n        fun `errors if there is nothing on the stack`() {\n            val ex = assertFails { Forth().evaluate(\"/\") }\n            assertEquals(\"empty stack\", ex.message)\n        }\n\n        @Ignore\n        @Test\n        fun `errors if there is only one value on the stack`() {\n            val ex = assertFails { Forth().evaluate(\"1 /\") }\n            assertEquals(\"only one value on the stack\", ex.message)\n        }\n    }\n\n    @Nested\n    inner class CombinedArithmetic {\n\n        @Ignore\n        @Test\n        fun `addition and subtraction`() =\n            assertEquals(listOf(-1), Forth().evaluate(\"1 2 + 4 -\"))\n\n        @Ignore\n        @Test\n        fun `multiplication and division`() =\n            assertEquals(listOf(2), Forth().evaluate(\"2 4 * 3 /\"))\n    }\n\n    @Nested\n    inner class Dup {\n\n        @Ignore\n        @Test\n        fun `copies a value on the stack`() =\n            assertEquals(listOf(1, 1), Forth().evaluate(\"1 dup\"))\n\n        @Ignore\n        @Test\n        fun `copies the top value on the stack`() =\n            assertEquals(listOf(1, 2, 2), Forth().evaluate(\"1 2 dup\"))\n\n        @Ignore\n        @Test\n        fun `errors if there is nothing on the stack`() {\n            val ex = assertFails { Forth().evaluate(\"dup\") }\n            assertEquals(\"empty stack\", ex.message)\n        }\n    }\n\n    @Nested\n    inner class Drop {\n\n        @Ignore\n        @Test\n        fun `removes the top value on the stack if it is the only one`() =\n            assertEquals(emptyList(), Forth().evaluate(\"1 drop\"))\n\n        @Ignore\n        @Test\n        fun `removes the top value on the stack if it is not the only one`() =\n            assertEquals(listOf(1), Forth().evaluate(\"1 2 drop\"))\n\n        @Ignore\n        @Test\n        fun `errors if there is nothing on the stack`() {\n            val ex = assertFails { Forth().evaluate(\"drop\") }\n            assertEquals(\"empty stack\", ex.message)\n        }\n    }\n\n    @Nested\n    inner class Swap {\n\n        @Ignore\n        @Test\n        fun `swaps the top two values on the stack if they are the only ones`() =\n            assertEquals(listOf(2, 1), Forth().evaluate(\"1 2 swap\"))\n\n        @Ignore\n        @Test\n        fun `swaps the top two values on the stack if they are not the only ones`() =\n            assertEquals(listOf(1, 3, 2), Forth().evaluate(\"1 2 3 swap\"))\n\n        @Ignore\n        @Test\n        fun `errors if there is nothing on the stack`() {\n            val ex = assertFails { Forth().evaluate(\"swap\") }\n            assertEquals(\"empty stack\", ex.message)\n        }\n\n        @Ignore\n        @Test\n        fun `errors if there is only one value on the stack`() {\n            val ex = assertFails { Forth().evaluate(\"1 swap\") }\n            assertEquals(\"only one value on the stack\", ex.message)\n        }\n    }\n\n    @Nested\n    inner class Over {\n\n        @Ignore\n        @Test\n        fun `copies the second element if there are only two`() =\n            assertEquals(listOf(1, 2, 1), Forth().evaluate(\"1 2 over\"))\n\n        @Ignore\n        @Test\n        fun `copies the second element if there are more than two`() =\n            assertEquals(listOf(1, 2, 3, 2), Forth().evaluate(\"1 2 3 over\"))\n\n        @Ignore\n        @Test\n        fun `errors if there is nothing on the stack`() {\n            val ex = assertFails { Forth().evaluate(\"over\") }\n            assertEquals(\"empty stack\", ex.message)\n        }\n\n        @Ignore\n        @Test\n        fun `errors if there is only one value on the stack`() {\n            val ex = assertFails { Forth().evaluate(\"1 over\") }\n            assertEquals(\"only one value on the stack\", ex.message)\n        }\n    }\n\n    @Nested\n    inner class UserDefinedWords {\n\n        @Ignore\n        @Test\n        fun `can consist of built-in words`() = assertEquals(\n            listOf(1, 1, 1),\n            Forth().evaluate(\n                \": dup-twice dup dup ;\",\n                \"1 dup-twice\",\n            )\n        )\n\n        @Ignore\n        @Test\n        fun `execute in the right order`() = assertEquals(\n            listOf(1, 2, 3),\n            Forth().evaluate(\n                \": countup 1 2 3 ;\",\n                \"countup\",\n            )\n        )\n\n        @Ignore\n        @Test\n        fun `can override other user-defined words`() =\n            assertEquals(\n                listOf(1, 1, 1),\n                Forth().evaluate(\n                    \": foo dup ;\",\n                    \": foo dup dup ;\",\n                    \"1 foo\",\n                )\n            )\n\n        @Ignore\n        @Test\n        fun `can override built-in words`() = assertEquals(\n            listOf(1, 1), Forth().evaluate(\n                \": swap dup ;\",\n                \"1 swap\",\n            )\n        )\n\n        @Ignore\n        @Test\n        fun `can override built-in operators`() = assertEquals(\n            listOf(12), Forth().evaluate(\n                \": + * ;\",\n                \"3 4 +\",\n            )\n        )\n\n        @Ignore\n        @Test\n        fun `can use different words with the same name`() = assertEquals(\n            listOf(5, 6), Forth().evaluate(\n                \": foo 5 ;\",\n                \": bar foo ;\",\n                \": foo 6 ;\",\n                \"bar foo\",\n            )\n        )\n\n        @Ignore\n        @Test\n        fun `can define word that uses word with the same name`() = assertEquals(\n            listOf(11), Forth().evaluate(\n                \": foo 10 ;\",\n                \": foo foo 1 + ;\",\n                \"foo\",\n            )\n        )\n\n        @Ignore\n        @Test\n        fun `cannot redefine numbers`() {\n            val ex = assertFails { Forth().evaluate(\": 1 2 ;\") }\n            assertEquals(\"illegal operation\", ex.message)\n        }\n\n        @Ignore\n        @Test\n        fun `errors if executing a non-existent word`() {\n            val ex = assertFails { Forth().evaluate(\"foo\") }\n            assertEquals(\"undefined operation\", ex.message)\n        }\n    }\n\n    @Nested\n    inner class CaseInsensitivity {\n\n        @Ignore\n        @Test\n        fun `DUP is case-insensitive`() = assertEquals(listOf(1, 1, 1, 1), Forth().evaluate(\"1 DUP Dup dup\"))\n\n        @Ignore\n        @Test\n        fun `DROP is case-insensitive`() = assertEquals(listOf(1), Forth().evaluate(\"1 2 3 4 DROP Drop drop\"))\n\n        @Ignore\n        @Test\n        fun `SWAP is case-insensitive`() = assertEquals(listOf(2, 3, 4, 1), Forth().evaluate(\"1 2 SWAP 3 Swap 4 swap\"))\n\n        @Ignore\n        @Test\n        fun `OVER is case-insensitive`() = assertEquals(listOf(1, 2, 1, 2, 1), Forth().evaluate(\"1 2 OVER Over over\"))\n\n        @Ignore\n        @Test\n        fun `user-defined words are case-insensitive`() =\n            assertEquals(\n                listOf(1, 1, 1, 1),\n                Forth().evaluate(\": foo dup ;\", \"1 FOO Foo foo\")\n            )\n\n        @Ignore\n        @Test\n        fun `definitions are case-insensitive`() = assertEquals(\n            listOf(1, 1, 1, 1), Forth().evaluate(\n                \": SWAP DUP Dup dup ;\",\n                \"1 swap\",\n            )\n        )\n    }\n}\n"
  },
  {
    "path": "exercises/practice/gigasecond/.approaches/config.json",
    "content": "{\n  \"introduction\": {\n    \"authors\": [\n      \"bobahop\"\n    ]\n  },\n  \"approaches\": [\n    {\n      \"uuid\": \"54bff868-f84e-481e-ae00-bed8e960445e\",\n      \"slug\": \"secondary-constructor-atstartofday\",\n      \"title\": \"Secondary constructor with atStartOfDay\",\n      \"blurb\": \"Use a secondary constructor with atStartOfDay to return the answer.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "exercises/practice/gigasecond/.approaches/introduction.md",
    "content": "# Introduction\n\nThere are several ways to solve Gigasecond.\nOne approach is to use a [secondary constructor][constructors] with the [`atStartOfDay`][atstartofday] method of the [`LocalDate`][localdate] class.\n\n## Approach: Secondary constructor with `atStartOfDay`\n\n```kotlin\nimport java.time.LocalDate\nimport java.time.LocalDateTime\n\nclass Gigasecond(baseDatetime: LocalDateTime) {\n    private val gigaseconds: Long = 1_000_000_000\n    val date: LocalDateTime = baseDatetime.plusSeconds(gigaseconds)\n\n    constructor(baseDate: LocalDate) : this(baseDate.atStartOfDay())\n}\n```\n\nFor more information, check the [Secondary constructor with atStartOfDay approach][approach-secondary-constructor-atstartofday].\n\n[approach-secondary-constructor-atstartofday]: https://exercism.org/tracks/kotlin/exercises/gigasecond/approaches/secondary-constructor-atstartofday\n\n[constructors]: https://www.geeksforgeeks.org/kotlin-constructor/\n[atstartofday]: https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html#atStartOfDay--\n[localdate]: https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html\n"
  },
  {
    "path": "exercises/practice/gigasecond/.approaches/secondary-constructor-atstartofday/content.md",
    "content": "# Secondary constructor with `atStartOfDay`\n\n```kotlin\nimport java.time.LocalDate\nimport java.time.LocalDateTime\n\nclass Gigasecond(baseDatetime: LocalDateTime) {\n    private val gigaseconds: Long = 1_000_000_000\n    val date: LocalDateTime = baseDatetime.plusSeconds(gigaseconds)\n\n    constructor(baseDate: LocalDate) : this(baseDate.atStartOfDay())\n}\n```\n\nThis approach starts by importng from libraries for what is needed.\n\nThe `Gigasecond` class is defined with a [primary constructor][constructors] that takes a `LocalDateTime`.\n\nA [`private`][visibility] [`val`][variables] is defined to hold the value for one billion seconds.\nA `val` with a meaningful name is used instead of using the `1000000000` value as a [magic number][magic-number].\nNote that [digit separators][digit-separators] (`_`) can make long numbers more readable.\n\nAnother `val` is defined that uses the [`plusSeconds`][plusseconds] method to add a billion seconds to the value passed into the primary constructor.\n\nThe `constructor` keyword is used to define a secondary constructor that takes a `LocalDate`.\nIt uses the `this` keyword to call another constructor (in this case, the primary constructor.)\nThe [`atStartOfDay`][atstartofday] method is used to convert the `LocalDate` to the `LocalDateTime` type accepted by the primary constructor.\nCalling one constructor from another is referrred to as \"constructor chaining\".\n\n[constructors]: https://www.geeksforgeeks.org/kotlin-constructor/\n[visibility]: https://kotlinlang.org/docs/visibility-modifiers.html\n[variables]: https://kotlinlang.org/docs/basic-syntax.html#variables\n[magic-number]: https://en.wikipedia.org/wiki/Magic_number_(programming)\n[digit-separators]: https://docs.oracle.com/javase/7/docs/technotes/guides/language/underscores-literals.html\n[plusseconds]: https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html#plusSeconds-long-\n[atstartofday]: https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html#atStartOfDay--\n[localdate]: https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html\n"
  },
  {
    "path": "exercises/practice/gigasecond/.approaches/secondary-constructor-atstartofday/snippet.txt",
    "content": "class Gigasecond(baseDatetime: LocalDateTime) {\n    private val gigaseconds: Long = 1_000_000_000\n    val date: LocalDateTime = baseDatetime.plusSeconds(gigaseconds)\n\n    constructor(baseDate: LocalDate) : this(baseDate.atStartOfDay())\n}\n"
  },
  {
    "path": "exercises/practice/gigasecond/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to determine the date and time one gigasecond after a certain date.\n\nA gigasecond is one thousand million seconds.\nThat is a one with nine zeros after it.\n\nIf you were born on _January 24th, 2015 at 22:00 (10:00:00pm)_, then you would be a gigasecond old on _October 2nd, 2046 at 23:46:40 (11:46:40pm)_.\n"
  },
  {
    "path": "exercises/practice/gigasecond/.docs/introduction.md",
    "content": "# Introduction\n\nThe way we measure time is kind of messy.\nWe have 60 seconds in a minute, and 60 minutes in an hour.\nThis comes from ancient Babylon, where they used 60 as the basis for their number system.\nWe have 24 hours in a day, 7 days in a week, and how many days in a month?\nWell, for days in a month it depends not only on which month it is, but also on what type of calendar is used in the country you live in.\n\nWhat if, instead, we only use seconds to express time intervals?\nThen we can use metric system prefixes for writing large numbers of seconds in more easily comprehensible quantities.\n\n- A food recipe might explain that you need to let the brownies cook in the oven for two kiloseconds (that's two thousand seconds).\n- Perhaps you and your family would travel to somewhere exotic for two megaseconds (that's two million seconds).\n- And if you and your spouse were married for _a thousand million_ seconds, you would celebrate your one gigasecond anniversary.\n\n~~~~exercism/note\nIf we ever colonize Mars or some other planet, measuring time is going to get even messier.\nIf someone says \"year\" do they mean a year on Earth or a year on Mars?\n\nThe idea for this exercise came from the science fiction novel [\"A Deepness in the Sky\"][vinge-novel] by author Vernor Vinge.\nIn it the author uses the metric system as the basis for time measurements.\n\n[vinge-novel]: https://www.tor.com/2017/08/03/science-fiction-with-something-for-everyone-a-deepness-in-the-sky-by-vernor-vinge/\n~~~~\n"
  },
  {
    "path": "exercises/practice/gigasecond/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"enixander\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"kytrinyx\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Gigasecond.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/GigasecondTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Gigasecond.kt\"\n    ]\n  },\n  \"blurb\": \"Given a moment, determine the moment that would be after a gigasecond has passed.\",\n  \"source\": \"Chapter 9 in Chris Pine's online Learn to Program tutorial.\",\n  \"source_url\": \"https://pine.fm/LearnToProgram/?Chapter=09\"\n}\n"
  },
  {
    "path": "exercises/practice/gigasecond/.meta/src/reference/kotlin/Gigasecond.kt",
    "content": "import java.time.LocalDate\nimport java.time.LocalDateTime\n\ndata class Gigasecond(val initialDateTime: LocalDateTime) {\n\n    constructor(initialDate: LocalDate): this(initialDate.atTime(0, 0))\n\n    val date = initialDateTime.plusSeconds(1_000_000_000)\n}\n"
  },
  {
    "path": "exercises/practice/gigasecond/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# date only specification of time\n\"92fbe71c-ea52-4fac-bd77-be38023cacf7\" = true\n\n# second test for date only specification of time\n\"6d86dd16-6f7a-47be-9e58-bb9fb2ae1433\" = true\n\n# third test for date only specification of time\n\"77eb8502-2bca-4d92-89d9-7b39ace28dd5\" = true\n\n# full time specified\n\"c9d89a7d-06f8-4e28-a305-64f1b2abc693\" = true\n\n# full time with day roll-over\n\"09d4e30e-728a-4b52-9005-be44a58d9eba\" = true\n"
  },
  {
    "path": "exercises/practice/gigasecond/.meta/version",
    "content": "2.0.0\n"
  },
  {
    "path": "exercises/practice/gigasecond/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/gigasecond/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/gigasecond/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/gigasecond/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/gigasecond/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/gigasecond/src/main/kotlin/Gigasecond.kt",
    "content": "import java.time.LocalDateTime\n\nclass Gigasecond {\n\n    // TODO: Implement proper constructor\n\n    val date: LocalDateTime = TODO(\"Implement this getter to complete the task\")\n}\n"
  },
  {
    "path": "exercises/practice/gigasecond/src/test/kotlin/GigasecondTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport java.time.LocalDate\nimport java.time.LocalDateTime\nimport java.time.Month\nimport kotlin.test.assertEquals\n\nclass GigasecondTest {\n\n    @Test\n    fun `date only specification of time`() {\n        val gigaSecond = Gigasecond(LocalDate.of(2011, Month.APRIL, 25))\n\n        assertEquals(LocalDateTime.of(2043, Month.JANUARY, 1, 1, 46, 40), gigaSecond.date)\n    }\n\n    @Ignore\n    @Test\n    fun `second test for date only specification of time`() {\n        val gigaSecond = Gigasecond(LocalDate.of(1977, Month.JUNE, 13))\n\n        assertEquals(LocalDateTime.of(2009, Month.FEBRUARY, 19, 1, 46, 40), gigaSecond.date)\n    }\n\n    @Ignore\n    @Test\n    fun `third test for date only specification of time`() {\n        val gigaSecond = Gigasecond(LocalDate.of(1959, Month.JULY, 19))\n\n        assertEquals(LocalDateTime.of(1991, Month.MARCH, 27, 1, 46, 40), gigaSecond.date)\n    }\n\n    @Ignore\n    @Test\n    fun `full time specified`() {\n        val gigaSecond = Gigasecond(LocalDateTime.of(2015, Month.JANUARY, 24, 22, 0, 0))\n\n        assertEquals(LocalDateTime.of(2046, Month.OCTOBER, 2, 23, 46, 40), gigaSecond.date)\n    }\n\n    @Ignore\n    @Test\n    fun `full time with day roll-over`() {\n        val gigaSecond = Gigasecond(LocalDateTime.of(2015, Month.JANUARY, 24, 23, 59, 59))\n\n        assertEquals(LocalDateTime.of(2046, Month.OCTOBER, 3, 1, 46, 39), gigaSecond.date)\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/grade-school/.docs/instructions.md",
    "content": "# Instructions\n\nGiven students' names along with the grade they are in, create a roster for the school.\n\nIn the end, you should be able to:\n\n- Add a student's name to the roster for a grade:\n  - \"Add Jim to grade 2.\"\n  - \"OK.\"\n- Get a list of all students enrolled in a grade:\n  - \"Which students are in grade 2?\"\n  - \"We've only got Jim right now.\"\n- Get a sorted list of all students in all grades.\n  Grades should be sorted as 1, 2, 3, etc., and students within a grade should be sorted alphabetically by name.\n  - \"Who is enrolled in school right now?\"\n  - \"Let me think.\n    We have Anna, Barb, and Charlie in grade 1, Alex, Peter, and Zoe in grade 2, and Jim in grade 5.\n    So the answer is: Anna, Barb, Charlie, Alex, Peter, Zoe, and Jim.\"\n\nNote that all our students only have one name (it's a small town, what do you want?), and each student cannot be added more than once to a grade or the roster.\nIf a test attempts to add the same student more than once, your implementation should indicate that this is incorrect.\n"
  },
  {
    "path": "exercises/practice/grade-school/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"kytrinyx\",\n    \"lihofm\",\n    \"mdowds\",\n    \"mikegehard\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"tehbilly\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/GradeSchool.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/SchoolTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/GradeSchool.kt\"\n    ]\n  },\n  \"blurb\": \"Given students' names along with the grade that they are in, create a roster for the school.\",\n  \"source\": \"A pairing session with Phil Battos at gSchool\"\n}\n"
  },
  {
    "path": "exercises/practice/grade-school/.meta/src/reference/kotlin/GradeSchool.kt",
    "content": "class School {\n\n    private val database = mutableMapOf<Int, List<String>>()\n\n    fun add(student: String, grade: Int) {\n        database[grade] = (grade(grade) + student).sorted()\n    }\n\n    fun grade(grade: Int) = database[grade] ?: listOf()\n\n    fun roster() = database.toSortedMap().map { it.value }.flatten()\n\n}\n"
  },
  {
    "path": "exercises/practice/grade-school/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# Adding a student adds them to the sorted roster\n\"6d0a30e4-1b4e-472e-8e20-c41702125667\" = true\n\n# Adding more student adds them to the sorted roster\n\"233be705-dd58-4968-889d-fb3c7954c9cc\" = true\n\n# Adding students to different grades adds them to the same sorted roster\n\"75a51579-d1d7-407c-a2f8-2166e984e8ab\" = true\n\n# Roster returns an empty list if there are no students enrolled\n\"a3f0fb58-f240-4723-8ddc-e644666b85cc\" = true\n\n# Student names with grades are displayed in the same sorted roster\n\"180a8ff9-5b94-43fc-9db1-d46b4a8c93b6\" = true\n\n# Grade returns the students in that grade in alphabetical order\n\"1bfbcef1-e4a3-49e8-8d22-f6f9f386187e\" = true\n\n# Grade returns an empty list if there are no students in that grade\n\"5e67aa3c-a3c6-4407-a183-d8fe59cd1630\" = true\n"
  },
  {
    "path": "exercises/practice/grade-school/.meta/version",
    "content": "1.0.1\n"
  },
  {
    "path": "exercises/practice/grade-school/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/grade-school/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/grade-school/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/grade-school/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/grade-school/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/grade-school/src/main/kotlin/GradeSchool.kt",
    "content": "class School {\n\n    fun add(student: String, grade: Int) {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun grade(grade: Int): List<String> {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun roster(): List<String> {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/grade-school/src/test/kotlin/SchoolTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass SchoolTest {\n    @Test\n    fun `adding a student adds them to the sorted roster`() =\n        students(\"Aimee\" to 2)\n            .everyone()\n            .shouldBe(listOf(\"Aimee\"))\n\n    @Ignore\n    @Test\n    fun `adding more student adds them to the sorted roster`() =\n        students(\n            \"Blair\" to 2,\n            \"James\" to 2,\n            \"Paul\" to 2\n        )\n            .everyone()\n            .shouldBe(listOf(\"Blair\", \"James\", \"Paul\"))\n\n    @Ignore\n    @Test\n    fun `adding students to different grades adds them to the same sorted roster`() =\n        students(\n            \"Chelsea\" to 3,\n            \"Logan\" to 7\n        )\n            .everyone()\n            .shouldBe(listOf(\"Chelsea\", \"Logan\"))\n\n    @Ignore\n    @Test\n    fun `roster returns an empty list if there are no students enrolled`() =\n        students()\n            .everyone()\n            .shouldBe(listOf())\n\n    @Ignore\n    @Test\n    fun `student names with grades are displayed in the same sorted roster`() =\n        students(\n            \"Peter\" to 2,\n            \"Anna\" to 1,\n            \"Barb\" to 1,\n            \"Zoe\" to 2,\n            \"Alex\" to 2,\n            \"Jim\" to 3,\n            \"Charlie\" to 1\n        )\n            .everyone()\n            .shouldBe(listOf(\"Anna\", \"Barb\", \"Charlie\", \"Alex\", \"Peter\", \"Zoe\", \"Jim\"))\n\n    @Ignore\n    @Test\n    fun `grade returns the students in that grade in alphabetical order`() =\n        students(\n            \"Franklin\" to 5,\n            \"Bradley\" to 5,\n            \"Jeff\" to 1\n        )\n            .fromGrade(5)\n            .shouldBe(listOf(\"Bradley\", \"Franklin\"))\n\n    @Ignore\n    @Test\n    fun `grade returns an empty list if there are no students in that grade`() =\n        students()\n            .fromGrade(1)\n            .shouldBe(listOf())\n}\n\nprivate class Students(vararg students: Pair<String, Int>) {\n    private val school = School()\n\n    init {\n        students.forEach { school.add(it.first, it.second) }\n    }\n\n    fun fromGrade(grade: Int) = StudentNames(school.grade(grade))\n    fun everyone() = StudentNames(school.roster())\n}\n\nprivate class StudentNames(private val names: List<String>) {\n    fun shouldBe(names: List<String>) = assertEquals(names, this.names)\n}\n\nprivate fun students(vararg students: Pair<String, Int>) = Students(*students)\n"
  },
  {
    "path": "exercises/practice/grains/.approaches/bit-shifting/content.md",
    "content": "# Bit-shifting\n\n```kotlin\nimport java.math.BigInteger\n\nobject Board {\n\n    fun getGrainCountForSquare(number: Int) =\n            if (number < 1 || number > 64)\n                    throw IllegalArgumentException(\"square must be between 1 and 64\")\n            else BigInteger.ONE.shiftLeft(number - 1)\n\n    fun getTotalGrainCount() = BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE)\n}\n```\n\nAn [object declaration][object] is used to define `Board` as essentially a [singleton][singleton] object instantiation of the class.\nThis is sufficient, since there is no object state that needs to change with each call of the `getGrainCountForSquare` or `getTotalGrainCount` methods.\n\nThe `getGrainCountForSquare` method is implemented by an `if/else` expression.\nAlthough the function has multiple lines, it consists only of the one `if/else` expression,\nso it is defined using [single-expression function][single-expression-function] syntax,\nwith the curly braces omitted from the function call and the return type [inferred][type-inference].\n\nAn `IllegalArgumentException` is thrown if the number is out of bounds.\n\nOtherwise, to calculate the grains on a square you can set a bit in the correct position of a [`BigInteger`][biginteger] value.\n\nTo understand how this works, consider just two squares that are represented in binary bits as `00`.\n\nYou use the [`BigInteger.shiftLeft()`][shiftleft] method to set `1` (i.e. [`BigInteger.ONE`][one]) at the position needed to make the correct decimal value.\n\n- To set the one grain on Square One you shift `1` for `0` positions to the left.\nSo, if `square` is `1` for square One, you subtract `square` by `1` to get `0`, which will not move it any positions to the left.\nThe result is binary `01`, which is decimal `1`.\n- To set the two grains on Square Two you shift `1` for `1` position to the left.\nSo, if `square` is `2` for square Two, you subtract `square` by `1` to get `1`, which will move it `1` position to the left.\nThe result is binary `10`, which is decimal `2`.\n\n| Square  | Shift Left By | Binary Value | Decimal Value |\n| ------- | ------------- | ------------ | ------------- |\n|       1 |             0 |         0001 |             1 |\n|       2 |             1 |         0010 |             2 |\n|       3 |             2 |         0100 |             4 |\n|       4 |             3 |         1000 |             8 |\n\nFor `getTotalGrainCount` we want all of the 64 bits set to `1` to get the sum of grains on all sixty-four squares.\nThe easy way to do this is to set the 65th bit to `1` and then subtract `1`.\nTo go back to our two-square example, if we can grow to three squares, then we can shift `BigInteger.ONE` two positions to the left for binary `100`,\nwhich is decimal `4`.\nBy subtracting `1` we get `3`, which is the total amount of grains on the two squares.\n\n| Square  | Binary Value | Decimal Value |\n| ------- | ------------ | ------------- |\n|       3 |         0100 |             4 |\n\n| Square  | Sum Binary Value | Sum Decimal Value |\n| ------- | ---------------- | ----------------- |\n|       1 |             0001 |                 1 |\n|       2 |             0011 |                 3 |\n\n[object]: https://kotlinlang.org/docs/object-declarations.html#object-declarations-overview\n[singleton]: https://en.wikipedia.org/wiki/Singleton_pattern\n[single-expression-function]: https://kotlinlang.org/docs/functions.html#single-expression-functions\n[type-inference]: https://kotlinlang.org/spec/type-inference.html\n[biginteger]: https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html\n[shiftleft]: https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#shiftLeft(int)\n[one]: https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#ONE\n"
  },
  {
    "path": "exercises/practice/grains/.approaches/bit-shifting/snippet.txt",
    "content": "fun getGrainCountForSquare(number: Int) =\n        if (number < 1 || number > 64)\n                throw IllegalArgumentException(\"square must be between 1 and 64\")\n        else BigInteger.ONE.shiftLeft(number - 1)\n\nfun getTotalGrainCount() = BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE)\n"
  },
  {
    "path": "exercises/practice/grains/.approaches/config.json",
    "content": "{\n  \"introduction\": {\n    \"authors\": [\n      \"bobahop\"\n    ]\n  },\n  \"approaches\": [\n    {\n      \"uuid\": \"4c786343-22f8-493f-8cb8-9c313f81ab59\",\n      \"slug\": \"bit-shifting\",\n      \"title\": \"Bit-shifting\",\n      \"blurb\": \"Use bit-shifting to raise 2 by a specified power.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "exercises/practice/grains/.approaches/introduction.md",
    "content": "# Introduction\n\nThere are various idiomatic approaches to solve Grains.\nOne approach can use `BigInteger` bit-shifting calculate the number on grains on a square.\n\n## General guidance\n\nThe key to solving Grains is to focus on each square having double the amount of grains as the square before it.\nThis means that the amount of grains grows exponentially.\nThe first square has one grain, which is `2` to the power of `0`.\nThe second square has two grains, which is `2` to the power of `1`.\nThe third square has four grains, which is `2` to the power of `2`.\nYou can see that the exponent, or power, that `2` is raised by is always one less than the square number.\n\n| Square | Power | Value                   |\n| ------ | ----- | ----------------------- |\n| 1      | 0     | 2 to the power of 0 = 1 |\n| 2      | 1     | 2 to the power of 1 = 2 |\n| 3      | 2     | 2 to the power of 2 = 4 |\n| 4      | 3     | 2 to the power of 3 = 8 |\n\n## Approach: Bit-shifting\n\n```kotlin\nimport java.math.BigInteger\n\nobject Board {\n\n    fun getGrainCountForSquare(number: Int) =\n            if (number < 1 || number > 64)\n                    throw IllegalArgumentException(\"square must be between 1 and 64\")\n            else BigInteger.ONE.shiftLeft(number - 1)\n\n    fun getTotalGrainCount() = BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE)\n}\n```\n\nFor more information, check the [Bit-shifting approach][approach-bit-shifting].\n\n[approach-bit-shifting]: https://exercism.org/tracks/kotlin/exercises/grains/approaches/bit-shifting\n"
  },
  {
    "path": "exercises/practice/grains/.docs/instructions.md",
    "content": "# Instructions\n\nCalculate the number of grains of wheat on a chessboard.\n\nA chessboard has 64 squares.\nSquare 1 has one grain, square 2 has two grains, square 3 has four grains, and so on, doubling each time.\n\nWrite code that calculates:\n\n- the number of grains on a given square\n- the total number of grains on the chessboard\n"
  },
  {
    "path": "exercises/practice/grains/.docs/introduction.md",
    "content": "# Introduction\n\nThere once was a wise servant who saved the life of a prince.\nThe king promised to pay whatever the servant could dream up.\nKnowing that the king loved chess, the servant told the king he would like to have grains of wheat.\nOne grain on the first square of a chessboard, with the number of grains doubling on each successive square.\n"
  },
  {
    "path": "exercises/practice/grains/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Grains.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/BoardTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Grains.kt\"\n    ]\n  },\n  \"blurb\": \"Calculate the number of grains of wheat on a chessboard given that the number on each square doubles.\",\n  \"source\": \"The CodeRanch Cattle Drive, Assignment 6\",\n  \"source_url\": \"https://web.archive.org/web/20240908084142/https://coderanch.com/wiki/718824/Grains\"\n}\n"
  },
  {
    "path": "exercises/practice/grains/.meta/src/reference/kotlin/Grains.kt",
    "content": "import java.math.BigInteger\n\nprivate const val SQUARE_COUNT = 64\nprivate const val INVALID_SQUARE_NUMBER_MESSAGE = \"Only integers between 1 and $SQUARE_COUNT (inclusive) are allowed\"\n\nobject Board {\n\n    fun getGrainCountForSquare(number: Int): BigInteger {\n        require(number > 0)             { INVALID_SQUARE_NUMBER_MESSAGE }\n        require(number <= SQUARE_COUNT) { INVALID_SQUARE_NUMBER_MESSAGE }\n\n        return BigInteger.valueOf(2).pow(number - 1)\n    }\n\n    fun getTotalGrainCount(): BigInteger {\n        return (1..SQUARE_COUNT)\n            .map { getGrainCountForSquare(it) }\n            .reduce { i1, i2 -> i1.add(i2) }\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/grains/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# 1\n\"9fbde8de-36b2-49de-baf2-cd42d6f28405\" = true\n\n# 2\n\"ee1f30c2-01d8-4298-b25d-c677331b5e6d\" = true\n\n# 3\n\"10f45584-2fc3-4875-8ec6-666065d1163b\" = true\n\n# 4\n\"a7cbe01b-36f4-4601-b053-c5f6ae055170\" = true\n\n# 16\n\"c50acc89-8535-44e4-918f-b848ad2817d4\" = true\n\n# 32\n\"acd81b46-c2ad-4951-b848-80d15ed5a04f\" = true\n\n# 64\n\"c73b470a-5efb-4d53-9ac6-c5f6487f227b\" = true\n\n# square 0 raises an exception\n\"1d47d832-3e85-4974-9466-5bd35af484e3\" = true\n\n# negative square raises an exception\n\"61974483-eeb2-465e-be54-ca5dde366453\" = true\n\n# square greater than 64 raises an exception\n\"a95e4374-f32c-45a7-a10d-ffec475c012f\" = true\n\n# returns the total number of grains on the board\n\"6eb07385-3659-4b45-a6be-9dc474222750\" = true\n"
  },
  {
    "path": "exercises/practice/grains/.meta/version",
    "content": "1.2.0\n"
  },
  {
    "path": "exercises/practice/grains/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/grains/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/grains/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/grains/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/grains/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/grains/src/main/kotlin/Grains.kt",
    "content": "import java.math.BigInteger\n\nobject Board {\n\n    fun getGrainCountForSquare(number: Int): BigInteger {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun getTotalGrainCount(): BigInteger {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/grains/src/test/kotlin/BoardTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport java.math.BigInteger\nimport kotlin.test.assertEquals\n\nclass BoardTest {\n\n    @Test\n    fun `per square - 1`() = assertGrainsEqual(1, 1)\n\n    @Ignore\n    @Test\n    fun `per square - 2`() = assertGrainsEqual(2, 2)\n\n    @Ignore\n    @Test\n    fun `per square - 3`() = assertGrainsEqual(3, 4)\n\n    @Ignore\n    @Test\n    fun `per square - 4`() = assertGrainsEqual(4, 8)\n\n    @Ignore\n    @Test\n    fun `per square - 16`() = assertGrainsEqual(16, 32768)\n\n    @Ignore\n    @Test\n    fun `per square - 32`() = assertGrainsEqual(32, 2147483648)\n\n    @Ignore\n    @Test\n    fun `per square - 64`() = assertGrainsEqual(64, \"9223372036854775808\")\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid input - square 0`() {\n        grains(0)\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid input - negative square`() {\n        grains(-1)\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid input - square after 64`() {\n        grains(65)\n    }\n\n    @Ignore\n    @Test\n    fun `total - all grains on board`() {\n        assertEquals(BigInteger(\"18446744073709551615\"), Board.getTotalGrainCount())\n    }\n}\n\nprivate fun assertGrainsEqual(cell: Int, expectation: String) =\n        assertEquals(BigInteger(expectation), grains(cell))\n\nprivate fun assertGrainsEqual(cell: Int, expectation: Long) =\n        assertEquals(BigInteger.valueOf(expectation), grains(cell))\n\nprivate fun grains(cell: Int) = Board.getGrainCountForSquare(cell)\n"
  },
  {
    "path": "exercises/practice/hamming/.approaches/config.json",
    "content": "{\n  \"introduction\": {\n    \"authors\": [\n      \"bobahop\"\n    ]\n  },\n  \"approaches\": [\n    {\n      \"uuid\": \"edb06fc9-9d11-4102-af5f-d3d2912b64df\",\n      \"slug\": \"zip-count\",\n      \"title\": \"zip with count\",\n      \"blurb\": \"Use zip with count to iterate to the answer.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "exercises/practice/hamming/.approaches/introduction.md",
    "content": "# Introduction\n\nThere are several ways to solve Hamming.\nOne approach is to use [`zip`][zip] with [`count`][count].\n\n## Approach: `zip` with `count`\n\n```kotlin\nobject Hamming {\n\n    fun compute(leftStrand: String, rightStrand: String) =\n        if (leftStrand.length != rightStrand.length)\n            throw IllegalArgumentException(\"left and right strands must be of equal length\")\n        else\n            (leftStrand zip rightStrand).count { it.first != it.second }\n}\n```\n\nFor more information, check the [`zip` with `count` approach][approach-zip-count].\n\n[approach-zip-count]: https://exercism.org/tracks/kotlin/exercises/hamming/approaches/zip-count\n[zip]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/zip.html\n[count]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/count.html\n"
  },
  {
    "path": "exercises/practice/hamming/.approaches/zip-count/content.md",
    "content": "# `zip` with `count`\n\n```kotlin\nobject Hamming {\n\n    fun compute(leftStrand: String, rightStrand: String) =\n        if (leftStrand.length != rightStrand.length)\n            throw IllegalArgumentException(\"left and right strands must be of equal length\")\n        else\n            (leftStrand zip rightStrand).count { it.first != it.second }\n}\n```\n\nAn [object declaration][object] is used to define `Hamming` as essentially a [singleton][singleton] object instantiation of the class.\nThis is sufficient, since there is no object state that needs to change with each call of the `compute` method.\n\nThe `compute` method is implemented by an `if/else` expression.\nAlthough the function has multiple lines, it consists only of the one `if/else` expression,\nso it is defined using [single-expression function][single-expression-function] syntax,\nwith the curly braces omitted from the function call and the return type [inferred][type-inference].\n\nAn `IllegalArgumentException` is thrown if the two input `String`s are not the same length.\n\nOtherwise, the [`zip`][zip] function is used to make a sequence of [`Pair`][pair] values of the characters at the same index in both input `String`s.\nSince `zip` is marked as an [`infix`][infix] function, it can be called between the two strands (i.e. between the left receiver and the right parameter),\nas well as called `leftStrand.zip(rightStrand)`.\nWhich to use is a matter of stylistic preference.\n\nThe [`count`][count] function iterates the `Pair` values and uses the [`it`][it] keyword to count the `Pair` values that meet the Boolean condition\nof the first value in the current `Pair` not being equal to the second value in the `Pair`.\n\nFinally, the `compute` function returns the result of calling `count` on the zipped `Pair` values.\n\n[object]: https://kotlinlang.org/docs/object-declarations.html#object-declarations-overview\n[singleton]: https://en.wikipedia.org/wiki/Singleton_pattern\n[single-expression-function]: https://kotlinlang.org/docs/functions.html#single-expression-functions\n[type-inference]: https://kotlinlang.org/spec/type-inference.html\n[zip]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/zip.html\n[count]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/count.html\n[pair]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-pair/\n[infix]: https://kotlinlang.org/docs/functions.html#infix-notation\n[it]: https://kotlinlang.org/docs/lambdas.html#it-implicit-name-of-a-single-parameter\n"
  },
  {
    "path": "exercises/practice/hamming/.approaches/zip-count/snippet.txt",
    "content": "object Hamming {\n\n    fun compute(leftStrand: String, rightStrand: String) =\n        if (leftStrand.length != rightStrand.length)\n            throw IllegalArgumentException(\"left and right strands must be of equal length\")\n        else\n            (leftStrand zip rightStrand).count { it.first != it.second }\n}\n"
  },
  {
    "path": "exercises/practice/hamming/.docs/instructions.md",
    "content": "# Instructions\n\nCalculate the Hamming distance between two DNA strands.\n\nWe read DNA using the letters C, A, G and T.\nTwo strands might look like this:\n\n    GAGCCTACTAACGGGAT\n    CATCGTAATGACGGCCT\n    ^ ^ ^  ^ ^    ^^\n\nThey have 7 differences, and therefore the Hamming distance is 7.\n\n## Implementation notes\n\nThe Hamming distance is only defined for sequences of equal length, so an attempt to calculate it between sequences of different lengths should not work.\n"
  },
  {
    "path": "exercises/practice/hamming/.docs/introduction.md",
    "content": "# Introduction\n\nYour body is made up of cells that contain DNA.\nThose cells regularly wear out and need replacing, which they achieve by dividing into daughter cells.\nIn fact, the average human body experiences about 10 quadrillion cell divisions in a lifetime!\n\nWhen cells divide, their DNA replicates too.\nSometimes during this process mistakes happen and single pieces of DNA get encoded with the incorrect information.\nIf we compare two strands of DNA and count the differences between them, we can see how many mistakes occurred.\nThis is known as the \"Hamming distance\".\n\nThe Hamming distance is useful in many areas of science, not just biology, so it's a nice phrase to be familiar with :)\n"
  },
  {
    "path": "exercises/practice/hamming/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"ErikSchierboom\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Hamming.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/HammingTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Hamming.kt\"\n    ]\n  },\n  \"blurb\": \"Calculate the Hamming distance between two DNA strands.\",\n  \"source\": \"The Calculating Point Mutations problem at Rosalind\",\n  \"source_url\": \"https://rosalind.info/problems/hamm/\"\n}\n"
  },
  {
    "path": "exercises/practice/hamming/.meta/src/reference/kotlin/Hamming.kt",
    "content": "object Hamming {\n\n    fun compute(leftStrand: String, rightStrand: String): Int {\n        require(leftStrand.length == rightStrand.length) { \"left and right strands must be of equal length\" }\n\n        val commonPairs = leftStrand.zip(rightStrand)\n        return commonPairs.count { it.first != it.second }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/hamming/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# empty strands\n\"f6dcb64f-03b0-4b60-81b1-3c9dbf47e887\" = true\n\n# single letter identical strands\n\"54681314-eee2-439a-9db0-b0636c656156\" = true\n\n# single letter different strands\n\"294479a3-a4c8-478f-8d63-6209815a827b\" = true\n\n# long identical strands\n\"9aed5f34-5693-4344-9b31-40c692fb5592\" = true\n\n# long different strands\n\"cd2273a5-c576-46c8-a52b-dee251c3e6e5\" = true\n\n# disallow first strand longer\n\"919f8ef0-b767-4d1b-8516-6379d07fcb28\" = true\n\n# disallow second strand longer\n\"8a2d4ed0-ead5-4fdd-924d-27c4cf56e60e\" = true\n\n# disallow left empty strand\n\"5dce058b-28d4-4ca7-aa64-adfe4e17784c\" = true\n\n# disallow right empty strand\n\"38826d4b-16fb-4639-ac3e-ba027dec8b5f\" = true\n"
  },
  {
    "path": "exercises/practice/hamming/.meta/version",
    "content": "2.3.0\n"
  },
  {
    "path": "exercises/practice/hamming/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/hamming/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/hamming/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/hamming/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/hamming/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/hamming/src/main/kotlin/Hamming.kt",
    "content": "object Hamming {\n\n    fun compute(leftStrand: String, rightStrand: String): Int {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/hamming/src/test/kotlin/HammingTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport org.junit.Rule\nimport org.junit.rules.ExpectedException\nimport kotlin.test.assertEquals\n\nclass HammingTest {\n\n    @Rule\n    @JvmField\n    var expectedException: ExpectedException = ExpectedException.none()\n\n    @Test\n    fun `empty strands`() {\n        assertEquals(0, Hamming.compute(\"\", \"\"))\n    }\n\n    @Ignore\n    @Test\n    fun `single letter identical strands`() {\n        assertEquals(0, Hamming.compute(\"A\", \"A\"))\n    }\n\n    @Ignore\n    @Test\n    fun `single letter different strands`() {\n        assertEquals(1, Hamming.compute(\"G\", \"T\"))\n    }\n\n    @Ignore\n    @Test\n    fun `long identical strands`() {\n        assertEquals(0, Hamming.compute(\"GGACTGAAATCTG\", \"GGACTGAAATCTG\"))\n    }\n\n    @Ignore\n    @Test\n    fun `long different strands`() {\n        assertEquals(9, Hamming.compute(\"GGACGGATTCTG\", \"AGGACGGATTCT\"))\n    }\n\n    @Ignore\n    @Test\n    fun `disallow first strand longer`() {\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"left and right strands must be of equal length\")\n\n        Hamming.compute(\"AATG\", \"AAA\")\n    }\n\n    @Ignore\n    @Test\n    fun `disallow second strand longer`() {\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"left and right strands must be of equal length\")\n\n        Hamming.compute(\"ATA\", \"AGTG\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/hello-world/.docs/instructions.append.md",
    "content": "# Instructions append\n\nSince this is your first Kotlin exercise, we've included a detailed TUTORIAL.md\nfile that guides you through your solution. Check it out for tips and\nassistance!\n\n"
  },
  {
    "path": "exercises/practice/hello-world/.docs/instructions.md",
    "content": "# Instructions\n\nThe classical introductory exercise.\nJust say \"Hello, World!\".\n\n[\"Hello, World!\"][hello-world] is the traditional first program for beginning programming in a new language or environment.\n\nThe objectives are simple:\n\n- Modify the provided code so that it produces the string \"Hello, World!\".\n- Run the test suite and make sure that it succeeds.\n- Submit your solution and check it at the website.\n\nIf everything goes well, you will be ready to fetch your first real exercise.\n\n[hello-world]: https://en.wikipedia.org/wiki/%22Hello,_world!%22_program\n"
  },
  {
    "path": "exercises/practice/hello-world/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"cswagner\"\n  ],\n  \"contributors\": [\n    \"bneevan\",\n    \"dector\",\n    \"HawkiesZA\",\n    \"jtigger\",\n    \"katrinleinweber\",\n    \"kytrinyx\",\n    \"lihofm\",\n    \"mdowds\",\n    \"mikegehard\",\n    \"Mouzourides\",\n    \"nithia\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"sup95\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/HelloWorld.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/HelloWorldTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/HelloWorld.kt\"\n    ]\n  },\n  \"blurb\": \"Exercism's classic introductory exercise. Just say \\\"Hello, World!\\\".\",\n  \"source\": \"This is an exercise to introduce users to using Exercism\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/%22Hello,_world!%22_program\"\n}\n"
  },
  {
    "path": "exercises/practice/hello-world/.meta/src/reference/kotlin/HelloWorld.kt",
    "content": "fun hello(): String {\n    return \"Hello, World!\"\n}\n"
  },
  {
    "path": "exercises/practice/hello-world/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# Say Hi!\n\"af9ffe10-dc13-42d8-a742-e7bdafac449d\" = true\n"
  },
  {
    "path": "exercises/practice/hello-world/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/hello-world/TUTORIAL.md",
    "content": "# Tutorial\n\nNOTE: You can also view the HTML version of this file here:\n<https://github.com/exercism/kotlin/blob/main/exercises/practice/hello-world/TUTORIAL.md>\n\n* [Introduction](#introduction)\n* [Exercise Structure](#exercise-structure)\n* [Solving \"Hello, World!\"](#solving-hello-world)\n* [Submitting your first iteration](#submitting-your-first-iteration)\n* [Next Steps](#next-steps)\n\n----\n\n# Introduction\n\nWelcome to the first exercise on the Kotlin track!\n\nThis is a step-by-step guide to solving this exercise.\n\nEach exercise comes with a set of tests.  The first pass through the\nexercise is about getting all of the tests to pass, one at a time.\n\nIf you have not installed the Java Development Kit and Gradle, you must do\nso now.  For help with this, see: https://exercism.org/docs/tracks/kotlin/installation\n\n----\n\nThis guide picks-up where [Running the Tests (in Kotlin)](https://exercism.org/docs/tracks/kotlin/tests)\nleft off.  If you haven't reviewed those instructions, do so now.\n\nThe following instructions work equally well on Windows, macOS and Linux.\n\n# Exercise Structure\n\nWhen you fetch a new Kotlin exercise, you will receive:\n\n* __one or more test files__ (always). These live in the `src/test/kotlin`\ndirectory and define a set of tests that our solution must satisfy before we\ncan safely declare that it is working.\n* __one or more starter files__ (initially). If provided, these live in the\n`src/main/kotlin` directory and define shells of the classes you will need\nin order to solve the current problem.\n\n\n\n# Solving \"Hello World!\"\n\n## Step 1: Run the tests against the starter solution\n\nUse Gradle to run the tests:\n\n```\n$ gradle test\n```\n\nThis command does a lot and displays a bunch of stuff.  Let's break it down...\n\n```\n:compileKotlin\nw: /Users/jtigger/exercism/exercises/kotlin/hello-world/src/main/kotlin/HelloWorld.kt: (1, 11): Parameter 'name' is never used\n:compileJava UP-TO-DATE\n:copyMainKotlinClasses\n:processResources UP-TO-DATE\n:classes UP-TO-DATE\n```\n\nEach line that begins with a colon (like `:compileKotlin`) is Gradle telling\nus that it's starting that task.  The first five tasks are about compiling\nthe source code of our *solution*.  We've done you a favor and included just\nenough code for the solution that it compiles.\n\nWhen a task is successful, it generally does not output anything.  This is\nwhy `:copyMainKotlinClasses` does not produce any additional output.\n\nA task may succeed but warn of a potential problem.  This is what we see from\n`:compileKotlin`.  The Kotlin compiler tells us that on line 1, 11 characters in\nof the `HelloWorld.kt` file, there is a parameter called `name` that was\ndeclared but never used.  Usually, warnings _are_ helpful and should be heeded.\nWe'll address this warning soon enough, but we're okay for now.\n\nThe next five tasks are about compiling source code of the *tests*.\n\n```\n:compileTestKotlin\n:compileTestJava UP-TO-DATE\n:copyTestKotlinClasses\n:processTestResources UP-TO-DATE\n:testClasses UP-TO-DATE\n```\n\n... with both sets of source code successfully compiled, Gradle turns to\nrunning the task you asked it to: executing the tests against the solution.\n\n```\n:test\n\nHelloWorldTest > helloWorldTest FAILED\n    org.junit.ComparisonFailure: expected:<[Hello, World]!> but was:<[Goodbye, Mars]!>\n        at org.junit.Assert.assertEquals(Assert.java:117)\n        at kotlin.test.junit.JUnitAsserter.assertEquals(JUnitSupport.kt:32)\n        at kotlin.test.AssertionsKt__AssertionsKt.assertEquals(Assertions.kt:63)\n        at kotlin.test.AssertionsKt.assertEquals(Unknown Source)\n        at kotlin.test.AssertionsKt__AssertionsKt.assertEquals$default(Assertions.kt:62)\n        at kotlin.test.AssertionsKt.assertEquals$default(Unknown Source)\n        at HelloWorldTest.helloWorldTest(HelloWorldTest.kt:8)\n\n1 test completed, 1 failed\n:test FAILED\n\nFAILURE: Build failed with an exception.\n\n* What went wrong:\nExecution failed for task ':test'.\n> There were failing tests. See the report at: file:///Users/jtigger/exercism/exercises/kotlin/hello-world/build/reports/tests/index.html\n\n* Try:\nRun with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.\n\nBUILD FAILED\n\nTotal time: 7.473 secs\n```\n\nSeeing the word \"fail\" might give you the impression you've done\nsomething horribly wrong!  You haven't.  It's a whole lot of noise over\na single test not passing.\n\nLet's focus in on the important bits:\n\n```\nHelloWorldTest > helloWorldTest FAILED\n    org.junit.ComparisonFailure: expected:<[Hello, World!]> but was:<[Goodbye, Mars]!>\n```\n\n...is read: \"Within the test class named `HelloWorldTest`, the test method\n`helloWorldTest` did not pass because the solution did not satisfy an\nassertion.  Apparently, we expected to see the string 'Hello, World!' but\na blank string was returned instead.\n\nThe last line of the stack trace tells us exactly where this unsatisfied\nassertion lives:\n\n```\n        at HelloWorldTest.helloWorldTest(HelloWorldTest.kt:8)\n```\n\nLooks like the scene of the crime is on line 8 in the test file.\n\nKnowing these two facts,\n\n1. the return value was not what was expected, and\n2. the failure was on line 8 of the test,\n\nwe can turn this failure into success.\n\n## Step 2: Fix the Test!\n\nIn your favorite text editor, open `src/test/kotlin/HelloWorldTest.kt`\nand go to line 8.\n\n```kotlin\nassertEquals(\"Hello, World!\", hello())\n```\n\nThe test is expecting that `hello()`, returns \"Hello, World!\".  Instead, `hello()` is returning `\"Goodbye, Mars!\"`.\nLet's fix that.\n\nOpen `src/main/kotlin/HelloWorld.kt`.\n\n```kotlin\nfun hello(): String {\n   return \"Goodbye, Mars!\"\n}\n```\n\nLet's change that to return the expected string:\n\n```kotlin\nfun hello(): String {\n   return \"Hello, World!\"\n}\n```\n\nSave the file and run the tests again:\n\n```\n$ gradle test\n:compileKotlin\n:compileJava UP-TO-DATE\n:copyMainKotlinClasses\n:processResources UP-TO-DATE\n:classes UP-TO-DATE\n:compileTestKotlin\n:compileTestJava UP-TO-DATE\n:copyTestKotlinClasses UP-TO-DATE\n:processTestResources UP-TO-DATE\n:testClasses UP-TO-DATE\n:test\n\nHelloWorldTest > helloWorldTest PASSED\n\nBUILD SUCCESSFUL\n\nTotal time: 7.318 secs\n```\n\n\"BUILD SUCCESSFUL\"!  Woohoo! :)  You can see that `helloWorldTest()` test is\nnow passing.\n\nCongratulations!\n\n# Submitting your first iteration\n\nWith a working solution that we've reviewed, we're ready to submit it to\nexercism.io.\n\n```\n$ exercism submit src/main/kotlin/HelloWorld.kt\n```\n\n\n\n# Next Steps\n\nFrom here, there are a number of paths you can take.\n\n\n## Move on to another exercise\n\nThere are many more exercises you can practice with.  Grab another one\nfrom the [Kotlin track](https://exercism.org/tracks/kotlin).\n\n\n## Review (and comment on) others' submissions to this exercise\n\nThe heart of Exercism is the conversations about coding\npractices.  It's definitely fun to practice, but engaging with others\nboth in their attempts and your own is how you get feedback.  That feedback\ncan help point out what you're doing well and where you might need to\nimprove.\n\nSome submissions will be nearly identical to yours; others will be\ncompletely different.  Seeing both kinds can be instructive and interesting.\n\nNote that you can only view submissions of others for exercises you have\ncompleted yourself.  This enriches the experience of reading others' code\nbecause you'll have your own experience of trying to solve the problem.\n\nHere's an up-to-date list of submissions on the Kotlin track:\n\n<https://exercism.org/tracks/kotlin/exercises>\n\n\n\n## Submit another iteration\n\nYou are also encouraged to consider additional \"requirements\" on a given\nexercise.\n\nFor example, you could add a test or two that requires that the greeting\nuse the capitalized form on the person's name, regardless of the case they\nused.\n\nIn that situation, you'd:\n\n1. add a new test setting up that new expectation,\n2. implement that in the code (the same process we just went through\n   together, above).\n3. review your code for readability and refactor as you see fit.\n\nExercism practitioners who \"play\" with each exercise — over trying to go as\nfast as they can through the stream of exercises — report deep rewards.\n\n\n## Contribute to Exercism\n\nThe entire of Exercism is Open Source and is the labor of love for more\nthan 100 maintainers and many more contributors.\n\nA starting point to jumping in can be found here:\n\n<https://exercism.org/docs/building>\n\n----\n\nRegardless of what you decide to do next, we sincerely hope you learn\nand enjoy being part of this community.  If at any time you need assistance\ndo not hesitate to ask for help:\n\n<https://exercism.org/docs/using/contact>\n\nCheers!\n"
  },
  {
    "path": "exercises/practice/hello-world/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/hello-world/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/hello-world/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/hello-world/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/hello-world/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/hello-world/src/main/kotlin/HelloWorld.kt",
    "content": "fun hello(): String {\n    return \"Goodbye, Mars!\"\n}\n"
  },
  {
    "path": "exercises/practice/hello-world/src/test/kotlin/HelloWorldTest.kt",
    "content": "import org.junit.Test\nimport kotlin.test.assertEquals\n\nclass HelloWorldTest {\n\n    @Test\n    fun helloWorldTest() {\n        assertEquals(\"Hello, World!\", hello())\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/hexadecimal/.docs/instructions.md",
    "content": "# Instructions\n\nConvert a hexadecimal number, represented as a string (e.g. \"10af8c\"), to its decimal equivalent using first principles (i.e. no, you may not use built-in or external libraries to accomplish the conversion).\n\nOn the web we use hexadecimal to represent colors, e.g. green: 008000,\nteal: 008080, navy: 000080).\n\nThe program should handle invalid hexadecimal strings.\n"
  },
  {
    "path": "exercises/practice/hexadecimal/.meta/config.json",
    "content": "{\n  \"blurb\": \"Convert a hexadecimal number, represented as a string (e.g. \\\"10af8c\\\"), to its decimal equivalent using first principles (i.e. no, you may not use built-in or external libraries to accomplish the conversion).\",\n  \"authors\": [\"sdavids13\"],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"kytrinyx\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\"src/main/kotlin/Hexadecimal.kt\"],\n    \"test\": [\"src/test/kotlin/HexadecimalTest.kt\"],\n    \"example\": [\".meta/src/reference/kotlin/Hexadecimal.kt\"]\n  },\n  \"source\": \"All of Computer Science\",\n  \"source_url\": \"http://www.wolframalpha.com/examples/NumberBases.html\"\n}\n"
  },
  {
    "path": "exercises/practice/hexadecimal/.meta/src/reference/kotlin/Hexadecimal.kt",
    "content": "object Hexadecimal {\n    private val hexChars = ('0'..'9') + ('a'..'f')\n\n    fun toDecimal(s: String): Int {\n        return s.lowercase().fold(0) { accum, char ->\n            when (char) {\n                in hexChars -> hexChars.indexOf(char) + (accum * 16)\n                else -> return 0\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/hexadecimal/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/hexadecimal/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/hexadecimal/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/hexadecimal/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/hexadecimal/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/hexadecimal/src/main/kotlin/Hexadecimal.kt",
    "content": "object Hexadecimal {\n\n    fun toDecimal(s: String): Int {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/hexadecimal/src/test/kotlin/HexadecimalTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport org.junit.runner.RunWith\nimport org.junit.runners.Parameterized\nimport kotlin.test.assertEquals\n\n@RunWith(Parameterized::class)\nclass HexadecimalTest(val input: String, val expectedOutput: Int) {\n\n    companion object {\n        @JvmStatic\n        @Parameterized.Parameters(name = \"{index}: binary({0})={1}\")\n        fun data() = listOf(\n                arrayOf(\"1\", 1),\n                arrayOf(\"c\", 12),\n                arrayOf(\"10\", 16),\n                arrayOf(\"af\", 175),\n                arrayOf(\"AF\", 175),\n                arrayOf(\"100\", 256),\n                arrayOf(\"19ace\", 105166),\n                arrayOf(\"000000\", 0),\n                arrayOf(\"ffffff\", 16777215),\n                arrayOf(\"ffff00\", 16776960),\n\n                //Invalid input\n                arrayOf(\"carrot1\", 0),\n                arrayOf(\"abc10z\", 0),\n                arrayOf(\"g1\", 0)\n        )\n    }\n\n\n    @Test\n    fun hexStringToInt() {\n        assertEquals(expectedOutput, Hexadecimal.toDecimal(input))\n    }\n}\n"
  },
  {
    "path": "exercises/practice/isbn-verifier/.approaches/config.json",
    "content": "{\n  \"introduction\": {\n    \"authors\": [\n      \"bobahop\"\n    ]\n  },\n  \"approaches\": [\n    {\n      \"uuid\": \"addeaa3a-174d-45e4-9a50-47711b0bb097\",\n      \"slug\": \"fold-when-let\",\n      \"title\": \"fold, when, and let\",\n      \"blurb\": \"Use fold and when with let to return the answer.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "exercises/practice/isbn-verifier/.approaches/fold-when-let/content.md",
    "content": "# `fold` and `when` with `let`\n\n```kotlin\nclass IsbnVerifier {\n\n    fun isValid(number: String) =\n            number\n                    .fold(Pair(10, 0)) { (pos, sum), ch ->\n                        when {\n                            ch.isDigit() -> pos - 1 to sum + (ch.digitToInt() * pos)\n                            ch == 'X' && pos == 1 -> pos - 1 to sum + 10\n                            ch == '-' -> pos to sum\n                            else -> -1 to sum\n                        }\n                    }\n                    .let { it.first == 0 && it.second % 11 == 0 }\n}\n```\n\nSince there is no object state that needs to change with each call of the `isValid` method, the `IsbnVerifier` class _could_ be defined as an [object][object],\nmaking it essentially a [singleton][singleton] object instantiation of the class.\nHowever, as of this writing, the tests call `isValid` using an empty constructor for `IsbnVerifier` (e.g. `IsbnVerifier().isValid(isbn)`)\ninstead of calling `isValid` like a method on an object (e.g. `IsbnVerifier.isValid(isbn)`), which is why `IsbnVerifier` can't be defined as an `object`.\n\nThe `isValid` function is implemented as a call of [`fold`][fold] chained to [`let`][let].\nAlthough the `isValid` function has multiple lines, it consists only of the one expression resulting from the function chain,\nso it is defined using [single-expression function][single-expression-function] syntax,\nwith the curly braces omitted from the `isValid` function call and the return type [inferred][type-inference].\n\nThe [`fold`][fold] method is called on the input `String`.\nIts accumulating value is initialized as a [`Pair`][pair] of values that represent the updating position and the calculating sum,\nwith the position starting at `10`, and the `sum` starting with `0`.\nThe [lambda][lambda] of `fold` takes the accumulating `Pair` as well as the character being iterated.\n\nInside the lambda is a [`when`][when] expression to check the value of the current character being iterated.\nIf the character is a digit, then the `when` returns the current position subtracted by `1`,\nand also returns the `sum` plus the character's numeric value multiplied by the current position.\nIt returns the values as the accumulating `Pair` by using the [`to`][to] keyword.\n\nIf the character is an `X` and the position is `1`, then the current position subtracted by `1` and the `sum` plus `10` are returned.\n\nIf the character is a `-`, then the position and sum are returned as is.\n\nIf none of those cases for the `when` are matched, then the character is illegal, so `-1` and the sum are returned.\nThe `-1` is meant to make the final check for a valid position fail.\n\nAfter the fold has iterated all of the characters in the input string, the [`let`][let] function is used to check the values of the\naccumulating `Pair`.\nIf the position is at `0` and the `sum` is evenly divided by `11`, then `true` is returned from `let`, otherwise, `false` is returned.\n\nThe `isValid` function returns the result of calling `let`.\n\n[object]: https://kotlinlang.org/docs/object-declarations.html#object-declarations-overview\n[singleton]: https://en.wikipedia.org/wiki/Singleton_pattern\n[fold]: https://kotlinlang.org/docs/collection-aggregate.html#fold-and-reduce\n[when]: https://kotlinlang.org/docs/control-flow.html#when-expression\n[let]: https://kotlinlang.org/docs/scope-functions.html#let\n[single-expression-function]: https://kotlinlang.org/docs/functions.html#single-expression-functions\n[type-inference]: https://kotlinlang.org/spec/type-inference.html\n[pair]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-pair/\n[to]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/to.html\n[lambda]: https://kotlinlang.org/docs/lambdas.html#lambda-expressions-and-anonymous-functions\n"
  },
  {
    "path": "exercises/practice/isbn-verifier/.approaches/fold-when-let/snippet.txt",
    "content": ".fold(Pair(10, 0)) { (pos, sum), ch ->\n    when {\n        ch.isDigit() -> pos - 1 to sum + (ch.digitToInt() * pos)\n        ch == 'X' && pos == 1 -> pos - 1 to sum + 10\n        ch == '-' -> pos to sum\n        else -> -1 to sum\n    }\n}\n"
  },
  {
    "path": "exercises/practice/isbn-verifier/.approaches/introduction.md",
    "content": "# Introduction\n\nThere are several ways to solve Isbn Verifier.\nOne approach is to use [`fold`][fold] and [`when`][when] with [`let`][let].\n\n## Approach: `fold` and `when` with `let`\n\n```kotlin\nclass IsbnVerifier {\n\n    fun isValid(number: String) =\n            number\n                    .fold(Pair(10, 0)) { (pos, sum), ch ->\n                        when {\n                            ch.isDigit() -> pos - 1 to sum + (ch.digitToInt() * pos)\n                            ch == 'X' && pos == 1 -> pos - 1 to sum + 10\n                            ch == '-' -> pos to sum\n                            else -> -1 to sum\n                        }\n                    }\n                    .let { it.first == 0 && it.second % 11 == 0 }\n}\n```\n\nFor more information, check the [`fold` and `when` with `let` approach][approach-fold-when-let].\n\n[approach-fold-when-let]: https://exercism.org/tracks/kotlin/exercises/isbn-verifier/approaches/fold-when-let\n[fold]: https://kotlinlang.org/docs/collection-aggregate.html#fold-and-reduce\n[when]: https://kotlinlang.org/docs/control-flow.html#when-expression\n[let]: https://kotlinlang.org/docs/scope-functions.html#let\n"
  },
  {
    "path": "exercises/practice/isbn-verifier/.docs/instructions.md",
    "content": "# Instructions\n\nThe [ISBN-10 verification process][isbn-verification] is used to validate book identification numbers.\nThese normally contain dashes and look like: `3-598-21508-8`\n\n## ISBN\n\nThe ISBN-10 format is 9 digits (0 to 9) plus one check character (either a digit or an X only).\nIn the case the check character is an X, this represents the value '10'.\nThese may be communicated with or without hyphens, and can be checked for their validity by the following formula:\n\n```text\n(d₁ * 10 + d₂ * 9 + d₃ * 8 + d₄ * 7 + d₅ * 6 + d₆ * 5 + d₇ * 4 + d₈ * 3 + d₉ * 2 + d₁₀ * 1) mod 11 == 0\n```\n\nIf the result is 0, then it is a valid ISBN-10, otherwise it is invalid.\n\n## Example\n\nLet's take the ISBN-10 `3-598-21508-8`.\nWe plug it in to the formula, and get:\n\n```text\n(3 * 10 + 5 * 9 + 9 * 8 + 8 * 7 + 2 * 6 + 1 * 5 + 5 * 4 + 0 * 3 + 8 * 2 + 8 * 1) mod 11 == 0\n```\n\nSince the result is 0, this proves that our ISBN is valid.\n\n## Task\n\nGiven a string the program should check if the provided string is a valid ISBN-10.\nPutting this into place requires some thinking about preprocessing/parsing of the string prior to calculating the check digit for the ISBN.\n\nThe program should be able to verify ISBN-10 both with and without separating dashes.\n\n## Caveats\n\nConverting from strings to numbers can be tricky in certain languages.\nNow, it's even trickier since the check digit of an ISBN-10 may be 'X' (representing '10').\nFor instance `3-598-21507-X` is a valid ISBN-10.\n\n[isbn-verification]: https://en.wikipedia.org/wiki/International_Standard_Book_Number\n"
  },
  {
    "path": "exercises/practice/isbn-verifier/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"vmichalak\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/IsbnVerifier.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/IsbnVerifierTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/IsbnVerifier.kt\"\n    ]\n  },\n  \"blurb\": \"Check if a given string is a valid ISBN-10 number.\",\n  \"source\": \"Converting a string into a number and some basic processing utilizing a relatable real world example.\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digit_calculation\"\n}\n"
  },
  {
    "path": "exercises/practice/isbn-verifier/.meta/src/reference/kotlin/IsbnVerifier.kt",
    "content": "class IsbnVerifier {\n    fun isValid(number: String): Boolean {\n        val value: String = number.replace(\"-\", \"\")\n\n        if(!Regex(\"\"\"^(\\d{9}[\\dX])${'$'}\"\"\").matches(value)) {\n            return false\n        }\n\n        return value.mapIndexed { i, c -> (10 - i) * when {\n                c == 'X' && i == 9 -> 10\n                else -> Character.getNumericValue(c)\n            }\n        }.sum() % 11 == 0\n    }\n}"
  },
  {
    "path": "exercises/practice/isbn-verifier/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# valid isbn number\n\"0caa3eac-d2e3-4c29-8df8-b188bc8c9292\" = true\n\n# invalid isbn check digit\n\"19f76b53-7c24-45f8-87b8-4604d0ccd248\" = true\n\n# valid isbn number with a check digit of 10\n\"4164bfee-fb0a-4a1c-9f70-64c6a1903dcd\" = true\n\n# check digit is a character other than X\n\"3ed50db1-8982-4423-a993-93174a20825c\" = true\n\n# invalid character in isbn\n\"c19ba0c4-014f-4dc3-a63f-ff9aefc9b5ec\" = true\n\n# X is only valid as a check digit\n\"28025280-2c39-4092-9719-f3234b89c627\" = true\n\n# valid isbn without separating dashes\n\"f6294e61-7e79-46b3-977b-f48789a4945b\" = true\n\n# isbn without separating dashes and X as check digit\n\"185ab99b-3a1b-45f3-aeec-b80d80b07f0b\" = true\n\n# isbn without check digit and dashes\n\"7725a837-ec8e-4528-a92a-d981dd8cf3e2\" = true\n\n# too long isbn and no dashes\n\"47e4dfba-9c20-46ed-9958-4d3190630bdf\" = true\n\n# too short isbn\n\"737f4e91-cbba-4175-95bf-ae630b41fb60\" = true\n\n# isbn without check digit\n\"5458a128-a9b6-4ff8-8afb-674e74567cef\" = true\n\n# check digit of X should not be used for 0\n\"70b6ad83-d0a2-4ca7-a4d5-a9ab731800f7\" = true\n\n# empty isbn\n\"94610459-55ab-4c35-9b93-ff6ea1a8e562\" = true\n\n# input is 9 characters\n\"7bff28d4-d770-48cc-80d6-b20b3a0fb46c\" = true\n\n# invalid characters are not ignored\n\"ed6e8d1b-382c-4081-8326-8b772c581fec\" = true\n\n# input is too long but contains a valid isbn\n\"fb5e48d8-7c03-4bfb-a088-b101df16fdc3\" = true\n"
  },
  {
    "path": "exercises/practice/isbn-verifier/.meta/version",
    "content": "2.7.0\n"
  },
  {
    "path": "exercises/practice/isbn-verifier/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/isbn-verifier/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/isbn-verifier/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/isbn-verifier/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/isbn-verifier/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/isbn-verifier/src/main/kotlin/IsbnVerifier.kt",
    "content": "class IsbnVerifier {\n\n    fun isValid(number: String): Boolean {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/isbn-verifier/src/test/kotlin/IsbnVerifierTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertFalse\nimport kotlin.test.assertTrue\n\nclass IsbnVerifierTest {\n    @Test\n    fun `valid - reguar isbn`() = assertValid(\"3-598-21508-8\")\n\n    @Ignore\n    @Test\n    fun `invalid - check digit`() = assertInvalid(\"3-598-21508-9\")\n\n    @Ignore\n    @Test\n    fun `valid - check digit is 10`() = assertValid(\"3-598-21507-X\")\n\n    @Ignore\n    @Test\n    fun `invalid - check digit is character other than X`() = assertInvalid(\"3-598-21507-A\")\n\n    @Ignore\n    @Test\n    fun `invalid - forbidden character`() = assertInvalid(\"3-598-P1581-X\")\n\n    @Ignore\n    @Test\n    fun `invalid - X is only valid as check digit`() = assertInvalid(\"3-598-2X507-9\")\n\n    @Ignore\n    @Test\n    fun `valid - without separating dashes`() = assertValid(\"3598215088\")\n\n    @Ignore\n    @Test\n    fun `valid - without separating dashes and X as check digit`() = assertValid(\"359821507X\")\n\n    @Ignore\n    @Test\n    fun `invalid - without check digit and dashes`() = assertInvalid(\"359821507\")\n\n    @Ignore\n    @Test\n    fun `invalid - too long and no dashes`() = assertInvalid(\"3598215078X\")\n\n    @Ignore\n    @Test\n    fun `invalid - too short`() = assertInvalid(\"00\")\n\n    @Ignore\n    @Test\n    fun `invalid - without check digit`() = assertInvalid(\"3-598-21507\")\n\n    @Ignore\n    @Test\n    fun `invalid - check digit of X is not used for 0`() = assertInvalid(\"3-598-21515-X\")\n\n    @Ignore\n    @Test\n    fun `invalid - empty`() = assertInvalid(\"\")\n\n    @Ignore\n    @Test\n    fun `invalid - input is 9 characters`() = assertInvalid(\"134456729\")\n\n    @Ignore\n    @Test\n    fun `invalid - prohibited characters are not ignored`() = assertInvalid(\"3132P34035\")\n\n    @Ignore\n    @Test\n    fun `invalid - too long but contains valid isbn`() = assertInvalid(\"98245726788\")\n}\n\nprivate fun assertValid(isbn: String) = assertTrue(IsbnVerifier().isValid(isbn))\n\nprivate fun assertInvalid(isbn: String) = assertFalse(IsbnVerifier().isValid(isbn))\n"
  },
  {
    "path": "exercises/practice/isogram/.docs/instructions.md",
    "content": "# Instructions\n\nDetermine if a word or phrase is an isogram.\n\nAn isogram (also known as a \"non-pattern word\") is a word or phrase without a repeating letter, however spaces and hyphens are allowed to appear multiple times.\n\nExamples of isograms:\n\n- lumberjacks\n- background\n- downstream\n- six-year-old\n\nThe word _isograms_, however, is not an isogram, because the s repeats.\n"
  },
  {
    "path": "exercises/practice/isogram/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"gandrianakis\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Isogram.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/IsogramTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Isogram.kt\"\n    ]\n  },\n  \"blurb\": \"Determine if a word or phrase is an isogram.\",\n  \"source\": \"Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Isogram\"\n}\n"
  },
  {
    "path": "exercises/practice/isogram/.meta/src/reference/kotlin/Isogram.kt",
    "content": "object Isogram {\n\n    fun isIsogram(input: String): Boolean {\n        val sanitizedInput = input.lowercase().replace(\"[.!?\\\\-\\\\s]\".toRegex(), \"\")\n        val charCounts = sanitizedInput.toList().countBy()\n        return !charCounts.any { it.value > 1 }\n    }\n\n}\n\n\nfun <T> Iterable<T>.countBy() : Map<T, Int>  = this.countBy { it }\n\nfun <T, M> Iterable<T>.countBy(transformer: (T) -> M) : Map<M, Int> {\n    val emptyMap = mapOf<M, Int>()\n    return this.fold(emptyMap) {accumulator, item ->\n        val transformedItem = transformer(item)\n\n        accumulator + Pair(transformedItem, accumulator.getOrElse(transformedItem) { 0 } + 1)\n    }\n}\n"
  },
  {
    "path": "exercises/practice/isogram/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# empty string\n\"a0e97d2d-669e-47c7-8134-518a1e2c4555\" = true\n\n# isogram with only lower case characters\n\"9a001b50-f194-4143-bc29-2af5ec1ef652\" = true\n\n# word with one duplicated character\n\"8ddb0ca3-276e-4f8b-89da-d95d5bae78a4\" = true\n\n# word with one duplicated character from the end of the alphabet\n\"6450b333-cbc2-4b24-a723-0b459b34fe18\" = true\n\n# longest reported english isogram\n\"a15ff557-dd04-4764-99e7-02cc1a385863\" = true\n\n# word with duplicated character in mixed case\n\"f1a7f6c7-a42f-4915-91d7-35b2ea11c92e\" = true\n\n# word with duplicated character in mixed case, lowercase first\n\"14a4f3c1-3b47-4695-b645-53d328298942\" = true\n\n# hypothetical isogrammic word with hyphen\n\"423b850c-7090-4a8a-b057-97f1cadd7c42\" = true\n\n# hypothetical word with duplicated character following hyphen\n\"93dbeaa0-3c5a-45c2-8b25-428b8eacd4f2\" = true\n\n# isogram with duplicated hyphen\n\"36b30e5c-173f-49c6-a515-93a3e825553f\" = true\n\n# made-up name that is an isogram\n\"cdabafa0-c9f4-4c1f-b142-689c6ee17d93\" = true\n\n# duplicated character in the middle\n\"5fc61048-d74e-48fd-bc34-abfc21552d4d\" = true\n\n# same first and last characters\n\"310ac53d-8932-47bc-bbb4-b2b94f25a83e\" = true\n"
  },
  {
    "path": "exercises/practice/isogram/.meta/version",
    "content": "1.7.0\n"
  },
  {
    "path": "exercises/practice/isogram/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/isogram/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/isogram/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/isogram/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/isogram/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/isogram/src/main/kotlin/Isogram.kt",
    "content": "object Isogram {\n\n    fun isIsogram(input: String): Boolean {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/isogram/src/test/kotlin/IsogramTest.kt",
    "content": "import org.junit.Test\nimport org.junit.runner.RunWith\nimport org.junit.runners.Parameterized\nimport kotlin.test.assertEquals\n\n@RunWith(Parameterized::class)\nclass IsogramTest(val input: String, val expectedOutput: Boolean) {\n\n    companion object {\n        @JvmStatic\n        @Parameterized.Parameters(name = \"{index}: isogram({0}) = {1}\")\n        fun data() = listOf(\n                arrayOf(\"\", true),\n                arrayOf(\"isogram\", true),\n                arrayOf(\"eleven\", false),\n                arrayOf(\"zzyzx\", false),\n                arrayOf(\"subdermatoglyphic\", true),\n                arrayOf(\"Alphabet\", false),\n                arrayOf(\"alphAbet\", false),\n                arrayOf(\"thumbscrew-japingly\", true),\n                arrayOf(\"thumbscrew-jappingly\", false),\n                arrayOf(\"six-year-old\", true),\n                arrayOf(\"Emily Jung Schwartzkopf\", true),\n                arrayOf(\"accentor\", false),\n                arrayOf(\"angola\", false)\n        )\n    }\n\n    @Test\n    fun test() {\n        assertEquals(expectedOutput, Isogram.isIsogram(input))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/kindergarten-garden/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to, given a diagram, determine which plants each child in the kindergarten class is responsible for.\n\nThere are 12 children in the class:\n\n- Alice, Bob, Charlie, David, Eve, Fred, Ginny, Harriet, Ileana, Joseph, Kincaid, and Larry.\n\nFour different types of seeds are planted:\n\n| Plant  | Diagram encoding |\n| ------ | ---------------- |\n| Grass  | G                |\n| Clover | C                |\n| Radish | R                |\n| Violet | V                |\n\nEach child gets four cups, two on each row:\n\n```text\n[window][window][window]\n........................ # each dot represents a cup\n........................\n```\n\nTheir teacher assigns cups to the children alphabetically by their names, which means that Alice comes first and Larry comes last.\n\nHere is an example diagram representing Alice's plants:\n\n```text\n[window][window][window]\nVR......................\nRG......................\n```\n\nIn the first row, nearest the windows, she has a violet and a radish.\nIn the second row she has a radish and some grass.\n\nYour program will be given the plants from left-to-right starting with the row nearest the windows.\nFrom this, it should be able to determine which plants belong to each student.\n\nFor example, if it's told that the garden looks like so:\n\n```text\n[window][window][window]\nVRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV\n```\n\nThen if asked for Alice's plants, it should provide:\n\n- Violets, radishes, violets, radishes\n\nWhile asking for Bob's plants would yield:\n\n- Clover, grass, clover, clover\n"
  },
  {
    "path": "exercises/practice/kindergarten-garden/.docs/introduction.md",
    "content": "# Introduction\n\nThe kindergarten class is learning about growing plants.\nThe teacher thought it would be a good idea to give the class seeds to plant and grow in the dirt.\nTo this end, the children have put little cups along the window sills and planted one type of plant in each cup.\nThe children got to pick their favorites from four available types of seeds: grass, clover, radishes, and violets.\n"
  },
  {
    "path": "exercises/practice/kindergarten-garden/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/KindergartenGarden.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/KindergartenGardenTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/KindergartenGarden.kt\"\n    ]\n  },\n  \"blurb\": \"Given a diagram, determine which plants each child in the kindergarten class is responsible for.\",\n  \"source\": \"Exercise by the JumpstartLab team for students at The Turing School of Software and Design.\",\n  \"source_url\": \"https://turing.edu\"\n}\n"
  },
  {
    "path": "exercises/practice/kindergarten-garden/.meta/src/reference/kotlin/KindergartenGarden.kt",
    "content": "class KindergartenGarden(private val diagram: String) {\n\n    val students = listOf(\n            \"Alice\", \"Bob\", \"Charlie\", \"David\",\n            \"Eve\", \"Fred\", \"Ginny\", \"Harriet\",\n            \"Ileana\", \"Joseph\", \"Kincaid\", \"Larry\")\n\n    val plants: Map<Char, String> = mapOf(\n            'V' to \"violets\",\n            'R' to \"radishes\",\n            'C' to \"clover\",\n            'G' to \"grass\")\n\n    fun getPlantsOfStudent(student: String): List<String> {\n        val idx = students.indexOf(student)\n        return diagram\n                .split(\"\\n\") // split into two lines\n                .map { it.substring(idx * 2, idx * 2 + 2) } // the two letters of that student in each line\n                .joinToString(\"\") // merge the two letters of each diagram line into one string\n                .map { plants[it]!! } // lookup the plant names by the given letters\n    }\n}\n"
  },
  {
    "path": "exercises/practice/kindergarten-garden/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# garden with single student\n\"1fc316ed-17ab-4fba-88ef-3ae78296b692\" = true\n\n# different garden with single student\n\"acd19dc1-2200-4317-bc2a-08f021276b40\" = true\n\n# garden with two students\n\"c376fcc8-349c-446c-94b0-903947315757\" = true\n\n# second student's garden\n\"2d620f45-9617-4924-9d27-751c80d17db9\" = true\n\n# third student's garden\n\"57712331-4896-4364-89f8-576421d69c44\" = true\n\n# first student's garden\n\"149b4290-58e1-40f2-8ae4-8b87c46e765b\" = true\n\n# second student's garden\n\"ba25dbbc-10bd-4a37-b18e-f89ecd098a5e\" = true\n\n# second to last student's garden\n\"6bb66df7-f433-41ab-aec2-3ead6e99f65b\" = true\n\n# last student's garden\n\"d7edec11-6488-418a-94e6-ed509e0fa7eb\" = true\n"
  },
  {
    "path": "exercises/practice/kindergarten-garden/.meta/version",
    "content": "1.1.1\n"
  },
  {
    "path": "exercises/practice/kindergarten-garden/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/kindergarten-garden/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/kindergarten-garden/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/kindergarten-garden/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/kindergarten-garden/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/kindergarten-garden/src/main/kotlin/KindergartenGarden.kt",
    "content": "class KindergartenGarden(private val diagram: String) {\n\n    fun getPlantsOfStudent(student: String): List<String> {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/kindergarten-garden/src/test/kotlin/KindergartenGardenTest.kt",
    "content": "import kotlin.test.Test\nimport kotlin.test.Ignore\nimport kotlin.test.assertEquals\n\nclass KindergartenGardenTest {\n\n    @Test\n    fun `single student`() {\n        val student = \"Alice\"\n        val diagram = \"RC\\nGG\"\n        val expected = listOf(\"radishes\", \"clover\", \"grass\", \"grass\")\n\n        assertEquals(expected, KindergartenGarden(diagram).getPlantsOfStudent(student))\n    }\n\n    @Ignore\n    @Test\n    fun `single student2`() {\n        val student = \"Alice\"\n        val diagram = \"VC\\nRC\"\n        val expected = listOf(\"violets\", \"clover\", \"radishes\", \"clover\")\n\n        assertEquals(expected, KindergartenGarden(diagram).getPlantsOfStudent(student))\n    }\n\n    @Ignore\n    @Test\n    fun `two students`() {\n        val student = \"Bob\"\n        val diagram = \"VVCG\\nVVRC\"\n        val expected = listOf(\"clover\", \"grass\", \"radishes\", \"clover\")\n\n        assertEquals(expected, KindergartenGarden(diagram).getPlantsOfStudent(student))\n    }\n\n    @Ignore\n    @Test\n    fun `one garden second student`() {\n        val student = \"Bob\"\n        val diagram = \"VVCCGG\\nVVCCGG\"\n        val expected = listOf(\"clover\", \"clover\", \"clover\", \"clover\")\n\n        assertEquals(expected, KindergartenGarden(diagram).getPlantsOfStudent(student))\n    }\n\n    @Ignore\n    @Test\n    fun `one garden third student`() {\n        val student = \"Charlie\"\n        val diagram = \"VVCCGG\\nVVCCGG\"\n        val expected = listOf(\"grass\", \"grass\", \"grass\", \"grass\")\n\n        assertEquals(expected, KindergartenGarden(diagram).getPlantsOfStudent(student))\n    }\n\n    @Ignore\n    @Test\n    fun `full garden first student`() {\n        val student = \"Alice\"\n        val diagram = \"VRCGVVRVCGGCCGVRGCVCGCGV\\nVRCCCGCRRGVCGCRVVCVGCGCV\"\n        val expected = listOf(\"violets\", \"radishes\", \"violets\", \"radishes\")\n\n        assertEquals(expected, KindergartenGarden(diagram).getPlantsOfStudent(student))\n    }\n\n    @Ignore\n    @Test\n    fun `full garden second student`() {\n        val student = \"Bob\"\n        val diagram = \"VRCGVVRVCGGCCGVRGCVCGCGV\\nVRCCCGCRRGVCGCRVVCVGCGCV\"\n        val expected = listOf(\"clover\", \"grass\", \"clover\", \"clover\")\n\n        assertEquals(expected, KindergartenGarden(diagram).getPlantsOfStudent(student))\n    }\n\n    @Ignore\n    @Test\n    fun `full garden second to last student`() {\n        val student = \"Kincaid\"\n        val diagram = \"VRCGVVRVCGGCCGVRGCVCGCGV\\nVRCCCGCRRGVCGCRVVCVGCGCV\"\n        val expected = listOf(\"grass\", \"clover\", \"clover\", \"grass\")\n\n        assertEquals(expected, KindergartenGarden(diagram).getPlantsOfStudent(student))\n    }\n\n    @Ignore\n    @Test\n    fun `full garden last student`() {\n        val student = \"Larry\"\n        val diagram = \"VRCGVVRVCGGCCGVRGCVCGCGV\\nVRCCCGCRRGVCGCRVVCVGCGCV\"\n        val expected = listOf(\"grass\", \"violets\", \"clover\", \"violets\")\n\n        assertEquals(expected, KindergartenGarden(diagram).getPlantsOfStudent(student))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/knapsack/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to determine which items to take so that the total value of her selection is maximized, taking into account the knapsack's carrying capacity.\n\nItems will be represented as a list of items.\nEach item will have a weight and value.\nAll values given will be strictly positive.\nLhakpa can take only one of each item.\n\nFor example:\n\n```text\nItems: [\n  { \"weight\": 5, \"value\": 10 },\n  { \"weight\": 4, \"value\": 40 },\n  { \"weight\": 6, \"value\": 30 },\n  { \"weight\": 4, \"value\": 50 }\n]\n\nKnapsack Maximum Weight: 10\n```\n\nFor the above, the first item has weight 5 and value 10, the second item has weight 4 and value 40, and so on.\nIn this example, Lhakpa should take the second and fourth item to maximize her value, which, in this case, is 90.\nShe cannot get more than 90 as her knapsack has a weight limit of 10.\n"
  },
  {
    "path": "exercises/practice/knapsack/.docs/introduction.md",
    "content": "# Introduction\n\nLhakpa is a [Sherpa][sherpa] mountain guide and porter.\nAfter months of careful planning, the expedition Lhakpa works for is about to leave.\nShe will be paid the value she carried to the base camp.\n\nIn front of her are many items, each with a value and weight.\nLhakpa would gladly take all of the items, but her knapsack can only hold so much weight.\n\n[sherpa]: https://en.wikipedia.org/wiki/Sherpa_people#Mountaineering\n"
  },
  {
    "path": "exercises/practice/knapsack/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lpizzinidev\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Knapsack.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/KnapsackTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Knapsack.kt\"\n    ]\n  },\n  \"blurb\": \"Given a knapsack that can only carry a certain weight, determine which items to put in the knapsack in order to maximize their combined value.\",\n  \"source\": \"Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Knapsack_problem\"\n}\n"
  },
  {
    "path": "exercises/practice/knapsack/.meta/src/reference/kotlin/Knapsack.kt",
    "content": "data class Item(val weight: Int, val value: Int)\n\nfun knapsack(maximumWeight: Int, items: List<Item>): Int {\n    val table = Array(items.size + 1) { IntArray(maximumWeight + 1) { 0 }}\n    items.forEachIndexed { index, item -> \n        for (c in 1..maximumWeight) {\n            if (item.weight > c) {\n                table[index+1][c] = table[index][c]\n            } else {\n                table[index+1][c] = Math.max(\n                    table[index][c],\n                    item.value + table[index][c-item.weight]\n                )\n            }\n        }\n    }\n    return table[items.size][maximumWeight]\n}"
  },
  {
    "path": "exercises/practice/knapsack/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# no items\n\"a4d7d2f0-ad8a-460c-86f3-88ba709d41a7\" = true\n\n# one item, too heavy\n\"1d39e98c-6249-4a8b-912f-87cb12e506b0\" = true\n\n# five items (cannot be greedy by weight)\n\"833ea310-6323-44f2-9d27-a278740ffbd8\" = true\n\n# five items (cannot be greedy by value)\n\"277cdc52-f835-4c7d-872b-bff17bab2456\" = true\n\n# example knapsack\n\"81d8e679-442b-4f7a-8a59-7278083916c9\" = true\n\n# 8 items\n\"f23a2449-d67c-4c26-bf3e-cde020f27ecc\" = true\n\n# 15 items\n\"7c682ae9-c385-4241-a197-d2fa02c81a11\" = true\n"
  },
  {
    "path": "exercises/practice/knapsack/.meta/version",
    "content": "1.0.0\n"
  },
  {
    "path": "exercises/practice/knapsack/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/knapsack/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/knapsack/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/knapsack/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/knapsack/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/knapsack/src/main/kotlin/Knapsack.kt",
    "content": "data class Item(val weight: Int, val value: Int)\n\nfun knapsack(maximumWeight: Int, items: List<Item>): Int {\n    TODO(\"Implement this function to complete the task\")\n}\n"
  },
  {
    "path": "exercises/practice/knapsack/src/test/kotlin/KnapsackTest.kt",
    "content": "import kotlin.test.Test\nimport kotlin.test.assertEquals\nimport kotlin.test.Ignore\n\nclass KnapsackTest {\n\n    @Test\n    fun `no items`() = assertEquals(0, knapsack(100, listOf()))\n\n    @Ignore\n    @Test\n    fun `one item, too heavy`() {\n        val items = listOf(Item(100, 1))\n        assertEquals(0, knapsack(10, items))\n    }\n\n    @Ignore\n    @Test\n    fun `five items (cannot be greedy by weight)`() {\n        val items = listOf(\n            Item(2, 5),\n            Item(2, 5),\n            Item(2, 5),\n            Item(2, 5),\n            Item(10, 21)\n        )\n        assertEquals(21, knapsack(10, items))\n    }\n\n    @Ignore\n    @Test\n    fun `five items (cannot be greedy by value)`() {\n        val items = listOf(\n            Item(2, 20),\n            Item(2, 20),\n            Item(2, 20),\n            Item(2, 20),\n            Item(10, 50)\n        )\n        assertEquals(80, knapsack(10, items))\n    }\n\n    @Ignore\n    @Test\n    fun `example knapsack`() {\n        val items = listOf(\n            Item(5, 10),\n            Item(4, 40),\n            Item(6, 30),\n            Item(4, 50)\n        )\n        assertEquals(90, knapsack(10, items))\n    }\n\n    @Ignore\n    @Test\n    fun `8 items`() {\n        val items = listOf(\n            Item(25, 350),\n            Item(35, 400),\n            Item(45, 450),\n            Item(5, 20),\n            Item(25, 70),\n            Item(3, 8),\n            Item(2, 5),\n            Item(2, 5)\n        )\n        assertEquals(900, knapsack(104, items))\n    }\n\n    @Ignore\n    @Test\n    fun `15 items`() {\n        val items = listOf(\n            Item(70, 135),\n            Item(73, 139),\n            Item(77, 149),\n            Item(80, 150),\n            Item(82, 156),\n            Item(87, 163),\n            Item(90, 173),\n            Item(94, 184),\n            Item(98, 192),\n            Item(106, 201),\n            Item(110, 210),\n            Item(113, 214),\n            Item(115, 221),\n            Item(118, 229),\n            Item(120, 240)\n        )\n        assertEquals(1458, knapsack(750, items))\n    }\n}"
  },
  {
    "path": "exercises/practice/largest-series-product/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to look for patterns in the long sequence of digits in the encrypted signal.\n\nThe technique you're going to use here is called the largest series product.\n\nLet's define a few terms, first.\n\n- **input**: the sequence of digits that you need to analyze\n- **series**: a sequence of adjacent digits (those that are next to each other) that is contained within the input\n- **span**: how many digits long each series is\n- **product**: what you get when you multiply numbers together\n\nLet's work through an example, with the input `\"63915\"`.\n\n- To form a series, take adjacent digits in the original input.\n- If you are working with a span of `3`, there will be three possible series:\n  - `\"639\"`\n  - `\"391\"`\n  - `\"915\"`\n- Then we need to calculate the product of each series:\n  - The product of the series `\"639\"` is 162 (`6 × 3 × 9 = 162`)\n  - The product of the series `\"391\"` is 27 (`3 × 9 × 1 = 27`)\n  - The product of the series `\"915\"` is 45 (`9 × 1 × 5 = 45`)\n- 162 is bigger than both 27 and 45, so the largest series product of `\"63915\"` is from the series `\"639\"`.\n  So the answer is **162**.\n"
  },
  {
    "path": "exercises/practice/largest-series-product/.docs/introduction.md",
    "content": "# Introduction\n\nYou work for a government agency that has intercepted a series of encrypted communication signals from a group of bank robbers.\nThe signals contain a long sequence of digits.\nYour team needs to use various digital signal processing techniques to analyze the signals and identify any patterns that may indicate the planning of a heist.\n"
  },
  {
    "path": "exercises/practice/largest-series-product/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"geoand\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/LargestSeriesProduct.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/SeriesTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/LargestSeriesProduct.kt\"\n    ]\n  },\n  \"blurb\": \"Given a string of digits, calculate the largest product for a contiguous substring of digits of length n.\",\n  \"source\": \"A variation on Problem 8 at Project Euler\",\n  \"source_url\": \"https://projecteuler.net/problem=8\"\n}\n"
  },
  {
    "path": "exercises/practice/largest-series-product/.meta/src/reference/kotlin/LargestSeriesProduct.kt",
    "content": "import java.lang.Math.max\n\nclass Series(private val digits: String) {\n\n    init {\n        require(digits.all { it.isDigit() })\n    }\n\n    fun getLargestProduct(span: Int): Long {\n        require(span >= 0)\n        require(digits.length >= span)\n\n        if(digits.isEmpty()) {\n            return 1\n        }\n\n        return calculateRec(digits.map { it.intValue() }, span, 0)\n    }\n\n    private tailrec fun calculateRec(digits: List<Int>, span: Int, maxSoFar: Long): Long {\n        val currentProduct = digits.subList(0, span).prod()\n        val newMax = kotlin.math.max(currentProduct, maxSoFar)\n        if(digits.size == span) { //since we won't be checking 'remainders' of the list, the end condition is simply when the size is the same as the span\n            return newMax\n        }\n\n        return calculateRec(digits.tail(), span, newMax)\n    }\n\n}\n\nfun Char.intValue() : Int  {\n    if(!this.isDigit()) {\n        throw IllegalArgumentException(\"Char ${this} is not a legal DEC character\")\n    }\n\n    return this.intDiff('0')\n}\n\nfun Char.intDiff(other: Char) = this.code - other.code\n\nfun List<Int>.prod() : Long = this.fold(1L) {productSoFar, item -> item*productSoFar}\n\nfun <T> List<T>.tail() = this.subList(1, this.size)\n"
  },
  {
    "path": "exercises/practice/largest-series-product/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# finds the largest product if span equals length\n\"7c82f8b7-e347-48ee-8a22-f672323324d4\" = true\n\n# can find the largest product of 2 with numbers in order\n\"88523f65-21ba-4458-a76a-b4aaf6e4cb5e\" = true\n\n# can find the largest product of 2\n\"f1376b48-1157-419d-92c2-1d7e36a70b8a\" = true\n\n# can find the largest product of 3 with numbers in order\n\"46356a67-7e02-489e-8fea-321c2fa7b4a4\" = true\n\n# can find the largest product of 3\n\"a2dcb54b-2b8f-4993-92dd-5ce56dece64a\" = true\n\n# can find the largest product of 5 with numbers in order\n\"673210a3-33cd-4708-940b-c482d7a88f9d\" = true\n\n# can get the largest product of a big number\n\"02acd5a6-3bbf-46df-8282-8b313a80a7c9\" = true\n\n# reports zero if the only digits are zero\n\"76dcc407-21e9-424c-a98e-609f269622b5\" = true\n\n# reports zero if all spans include zero\n\"6ef0df9f-52d4-4a5d-b210-f6fae5f20e19\" = true\n\n# rejects span longer than string length\n\"5d81aaf7-4f67-4125-bf33-11493cc7eab7\" = true\n\n# reports 1 for empty string and empty product (0 span)\n\"06bc8b90-0c51-4c54-ac22-3ec3893a079e\" = true\n\n# reports 1 for nonempty string and empty product (0 span)\n\"3ec0d92e-f2e2-4090-a380-70afee02f4c0\" = true\n\n# rejects empty string and nonzero span\n\"6d96c691-4374-4404-80ee-2ea8f3613dd4\" = true\n\n# rejects invalid character in digits\n\"7a38f2d6-3c35-45f6-8d6f-12e6e32d4d74\" = true\n\n# rejects negative span\n\"5fe3c0e5-a945-49f2-b584-f0814b4dd1ef\" = true\n"
  },
  {
    "path": "exercises/practice/largest-series-product/.meta/version",
    "content": "1.2.0\n"
  },
  {
    "path": "exercises/practice/largest-series-product/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/largest-series-product/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/largest-series-product/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/largest-series-product/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/largest-series-product/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/largest-series-product/src/main/kotlin/LargestSeriesProduct.kt",
    "content": "class Series {\n\n    // TODO: Implement proper constructor\n\n    fun getLargestProduct(span: Int): Long {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/largest-series-product/src/test/kotlin/SeriesTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass SeriesTest {\n\n    @Test\n    fun `corner - span equals length`() = assertLSPEquals(\"29\", 2, 18)\n\n    @Ignore\n    @Test\n    fun `numbers in order - span 2`() = assertLSPEquals(\"0123456789\", 2, 72)\n\n    @Ignore\n    @Test\n    fun `span 2`() = assertLSPEquals(\"576802143\", 2, 48)\n\n    @Ignore\n    @Test\n    fun `numbers in order - span 3`() = assertLSPEquals(\"0123456789\", 3, 504)\n\n    @Ignore\n    @Test\n    fun `span 3`() = assertLSPEquals(\"1027839564\", 3, 270)\n\n    @Ignore\n    @Test\n    fun `numbers in order - span 5`() = assertLSPEquals(\"0123456789\", 5, 15120)\n\n    @Ignore\n    @Test\n    fun `corner - long source sequence`() = assertLSPEquals(\"73167176531330624919225119674426574742355349194934\", 6, 23520)\n\n    @Ignore\n    @Test\n    fun `zeros - only`() = assertLSPEquals(\"0000\", 2, 0)\n\n    @Ignore\n    @Test\n    fun `zeros - dense`() = assertLSPEquals(\"99099\", 3, 0)\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `reject - span longer than string length`() {\n        lsp(\"123\", 4)\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `reject - empty string and nonzero span`() {\n        lsp(\"\", 1)\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `reject - nondigits in source sequence`() {\n        Series(\"1234a5\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `reject - negative span`() {\n        lsp(\"12345\", -1)\n    }\n}\n\nprivate fun assertLSPEquals(input: String, span: Int, lsp: Long) {\n    assertEquals(lsp(input, span), lsp)\n}\n\nprivate fun lsp(input: String, span: Int) = Series(input).getLargestProduct(span)\n\n"
  },
  {
    "path": "exercises/practice/leap/.approaches/boolean-chain/content.md",
    "content": "# Chain of Boolean expressions\n\n```kotlin\ndata class Year(val year: Int) {\n    val isLeap = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)\n}\n```\n\nThe first boolean expression uses the [modulus operator][modulus-operator] to check if the year is evenly divided by `4`.\n- If the year is not evenly divisible by `4`,\nthen the chain will \"short circuit\" due to the next operator being a [logical AND][logical-and] (`&&`), and will return `false`.\n- If the year _is_ evenly divisible by `4`, then the year is checked to _not_ be evenly divisible by `100`.\n- If the year is not evenly divisible by `100`, then the expression is `true` and the chain will \"short-circuit\" to return `true`,\nsince the next operator is a [logical OR][logical-or] (`||`).\n- If the year _is_ evenly divisible by `100`, then the expression is `false`, and the returned value from the chain will be if the year is evenly divisible by `400`.\n\n| year | year % 4 == 0 | year % 100 != 0 | year % 400 == 0 | is leap year |\n| ---- | ------------- | --------------- | --------------- | ------------ |\n| 2020 |          true |            true |   not evaluated |         true |\n| 2019 |         false |   not evaluated |   not evaluated |        false |\n| 2000 |          true |           false |            true |         true |\n| 1900 |          true |           false |           false |        false |\n\n\nThe chain of boolean expressions is efficient, as it proceeds from testing the most likely to least likely conditions.\n\n[modulus-operator]: https://www.programiz.com/kotlin-programming/operators\n[logical-and]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/and.html\n[logical-or]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/or.html\n"
  },
  {
    "path": "exercises/practice/leap/.approaches/boolean-chain/snippet.txt",
    "content": "data class Year(val year: Int) {\n    val isLeap = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)\n}\n"
  },
  {
    "path": "exercises/practice/leap/.approaches/built-in-method/content.md",
    "content": "# `isLeap()`\n\n```kotlin\nimport java.time.*\n\ndata class Year(val year: Int) {\n    val isLeap = LocalDate.of(year, Month.FEBRUARY, 28).isLeapYear\n}\n```\n\nThis may be considered a \"wicked cheat\" for this exercise, by simply passing the year into the [isLeap()][is-leap] method of the [Year][year] class.\nAlthough it is not in the spirit of this exercise, `isLeap()` would be the idiomatic way to determine if a year is a leap year in the \"real world\".\n\n[is-leap]: https://docs.oracle.com/javase/8/docs/api/java/time/Year.html#isLeap--\n[year]: https://docs.oracle.com/javase/8/docs/api/java/time/Year.html\n"
  },
  {
    "path": "exercises/practice/leap/.approaches/built-in-method/snippet.txt",
    "content": "import java.time.*\n\ndata class Year(val year: Int) {\n    val isLeap = LocalDate.of(year, Month.FEBRUARY, 28).isLeapYear\n}\n"
  },
  {
    "path": "exercises/practice/leap/.approaches/config.json",
    "content": "{\n  \"introduction\": {\n    \"authors\": [\n      \"bobahop\"\n    ]\n  },\n  \"approaches\": [\n    {\n      \"uuid\": \"21da8b43-0a72-4991-bfce-c2bc4a51d26b\",\n      \"slug\": \"boolean-chain\",\n      \"title\": \"Boolean chain\",\n      \"blurb\": \"Use a chain of boolean expressions.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    },\n    {\n      \"uuid\": \"03485733-b2e8-4be0-8a70-4a2d38ec2541\",\n      \"slug\": \"ternary-expression\",\n      \"title\": \"Ternary expression\",\n      \"blurb\": \"Use a ternary expression.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    },\n    {\n      \"uuid\": \"a5e8b72c-4061-4aa9-b8f1-0c4e0b577f94\",\n      \"slug\": \"plusdays\",\n      \"title\": \"plusDays method\",\n      \"blurb\": \"Use the plusDays method.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    },\n    {\n      \"uuid\": \"16c4ab8a-ae22-43db-911d-e8ee33b98cd8\",\n      \"slug\": \"built-in-method\",\n      \"title\": \"Built-in method\",\n      \"blurb\": \"Use the built-in method.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "exercises/practice/leap/.approaches/introduction.md",
    "content": "# Introduction\n\nThere are various idiomatic approaches to solve Leap.\nYou can use a chain of boolean expressions to test the conditions.\nOr you can use a [ternary expressions][ternary-expressions].\n\n## General guidance\n\nThe key to solving Leap is to know if the year is evenly divisible by `4`, `100` and `400`.\nFor determining that, you will use the [modulus operator][modulus-operator].\n\n## Approach: Chain of Boolean expressions\n\n```kotlin\ndata class Year(val year: Int) {\n    val isLeap = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)\n}\n```\n\nFor more information, check the [Boolean chain approach][approach-boolean-chain].\n\n## Approach: Ternary expression\n\n```kotlin\ndata class Year(val year: Int) {\n    val isLeap = if (year % 100 == 0) year % 400 == 0 else year % 4 == 0\n}\n```\n\nFor more information, check the [Ternary expression approach][approach-ternary-expression].\n\n## Other approaches\n\nBesides the aforementioned, idiomatic approaches, you could also approach the exercise as follows:\n\n## `plusDays()` approach:\n\nAdd a day to February 28th for the year and see if the new day is the 29th. For more information, see the [`plusDays()` approach][approach-plusdays].\n\n## Built-in method approach:\n\nUse the built-in method for the [Year][year]. For more information, see the [`isLeap()` approach][approach-isleap].\n\n## Which approach to use?\n\n- The chain of boolean expressions is most efficient, as it proceeds from the most likely to least likely conditions.\n  It has a maximum of three checks.\n- The ternary expression has a maximum of only two checks, but it starts from a less likely condition.\n- Using `plusDays()` or using the built-in `isLeap()` method may be considered \"cheats\" for the exercise,\n  but `isLeap()` would be the idiomatic way to check if a year is a leap year in Kotlin.\n\n[modulus-operator]: https://www.programiz.com/kotlin-programming/operators\n[ternary-expression]: https://kotlinlang.org/docs/control-flow.html#if-expression\n[approach-boolean-chain]: https://exercism.org/tracks/kotlin/exercises/leap/approaches/boolean-chain\n[approach-ternary-expression]: https://exercism.org/tracks/kotlin/exercises/leap/approaches/ternary-expression\n[approach-plusdays]: https://exercism.org/tracks/kotlin/exercises/leap/approaches/plusdays\n[year]: https://docs.oracle.com/javase/8/docs/api/java/time/Year.html\n[approach-isleap]: https://exercism.org/tracks/kotlin/exercises/leap/approaches/built-in-method\n"
  },
  {
    "path": "exercises/practice/leap/.approaches/plusdays/content.md",
    "content": "# `plusDays()` method\n\n```kotlin\nimport java.time.*\n\ndata class Year(val year: Int) {\n    val isLeap = LocalDate.of(year, Month.FEBRUARY, 28).plusDays(1).dayOfMonth == 29\n}\n```\n\nThis approach may be considered a \"cheat\" for this exercise.\nBy adding a day to February 28th for the year, you can see if the new day is the 29th or the 1st.\nIf it is the 29th, then the year is a leap year.\nThis is done by using the [`plusDays()`][plusdays] and [`getDayOfMonth()`][getdayofmonth] methods of the [LocalDate][localdate] class.\n\n[plusdays]: https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/time/LocalDate.html#plusDays(long)\n[getdayofmonth]: https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/time/LocalDate.html#getDayOfMonth()\n[localdate]: https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/time/LocalDate.html\n"
  },
  {
    "path": "exercises/practice/leap/.approaches/plusdays/snippet.txt",
    "content": "import java.time.*\n\ndata class Year(val year: Int) {\n    val isLeap = LocalDate.of(year, Month.FEBRUARY, 28).plusDays(1).dayOfMonth == 29\n}\n"
  },
  {
    "path": "exercises/practice/leap/.approaches/ternary-expression/content.md",
    "content": "Ternary expression\n\n```kotlin\ndata class Year(val year: Int) {\n    val isLeap = if (year % 100 == 0) year % 400 == 0 else year % 4 == 0\n}\n```\n\nA [ternary expression][ternary-expression] uses a maximum of two checks to determine if a year is a leap year.\n\nIt starts by testing the outlier condition of the year being evenly divisible by `100`.\nIt does this by using the [modulus operator][modulus-operator].\nIf the year is evenly divisible by `100`, then the expression is `true`, and the ternary expression returns if the year is evenly divisible by `400`.\nIf the year is _not_ evenly divisible by `100`, then the expression is `false`, and the ternary expression returns if the year is evenly divisible by `4`.\n\n| year | year % 100 == 0 | year % 400 == 0 | year % 4 == 0  | is leap year |\n| ---- | --------------- | --------------- | -------------- | ------------ |\n| 2020 |           false |   not evaluated |           true |        true  |\n| 2019 |           false |   not evaluated |          false |       false  |\n| 2000 |           true  |            true |  not evaluated |        true  |\n| 1900 |           true  |           false |  not evaluated |        false |\n\nAlthough it uses a maximum of only two checks, the ternary expression tests an outlier condition first,\nmaking it less efficient than another approach that would first test if the year is evenly divisible by `4`,\nwhich is more likely than the year being evenly divisible by `100`.\n\n[modulus-operator]: https://www.programiz.com/kotlin-programming/operators\n[ternary-expression]: https://kotlinlang.org/docs/control-flow.html#if-expression\n"
  },
  {
    "path": "exercises/practice/leap/.approaches/ternary-expression/snippet.txt",
    "content": "data class Year(val year: Int) {\n    val isLeap = if (year % 100 == 0) year % 400 == 0 else year % 4 == 0\n}\n"
  },
  {
    "path": "exercises/practice/leap/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to determine whether a given year is a leap year.\n"
  },
  {
    "path": "exercises/practice/leap/.docs/introduction.md",
    "content": "# Introduction\n\nA leap year (in the Gregorian calendar) occurs:\n\n- In every year that is evenly divisible by 4.\n- Unless the year is evenly divisible by 100, in which case it's only a leap year if the year is also evenly divisible by 400.\n\nSome examples:\n\n- 1997 was not a leap year as it's not divisible by 4.\n- 1900 was not a leap year as it's not divisible by 400.\n- 2000 was a leap year!\n\n~~~~exercism/note\nFor a delightful, four-minute explanation of the whole phenomenon of leap years, check out [this YouTube video](https://www.youtube.com/watch?v=xX96xng7sAE).\n~~~~\n"
  },
  {
    "path": "exercises/practice/leap/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Leap.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/LeapTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Leap.kt\"\n    ]\n  },\n  \"blurb\": \"Determine whether a given year is a leap year.\",\n  \"source\": \"CodeRanch Cattle Drive, Assignment 3\",\n  \"source_url\": \"https://web.archive.org/web/20240907033714/https://coderanch.com/t/718816/Leap\"\n}\n"
  },
  {
    "path": "exercises/practice/leap/.meta/src/reference/kotlin/Leap.kt",
    "content": "data class Year(private val year: Int) {\n    val isLeap: Boolean by lazy { divisibleBy(4) && (divisibleBy(400) || !divisibleBy(100)) }\n\n    private fun divisibleBy(i: Int) = year % i == 0\n}\n"
  },
  {
    "path": "exercises/practice/leap/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# year not divisible by 4 in common year\n\"6466b30d-519c-438e-935d-388224ab5223\" = true\n\n# year divisible by 2, not divisible by 4 in common year\n\"ac227e82-ee82-4a09-9eb6-4f84331ffdb0\" = true\n\n# year divisible by 4, not divisible by 100 in leap year\n\"4fe9b84c-8e65-489e-970b-856d60b8b78e\" = true\n\n# year divisible by 4 and 5 is still a leap year\n\"7fc6aed7-e63c-48f5-ae05-5fe182f60a5d\" = true\n\n# year divisible by 100, not divisible by 400 in common year\n\"78a7848f-9667-4192-ae53-87b30c9a02dd\" = true\n\n# year divisible by 100 but not by 3 is still not a leap year\n\"9d70f938-537c-40a6-ba19-f50739ce8bac\" = true\n\n# year divisible by 400 in leap year\n\"42ee56ad-d3e6-48f1-8e3f-c84078d916fc\" = true\n\n# year divisible by 400 but not by 125 is still a leap year\n\"57902c77-6fe9-40de-8302-587b5c27121e\" = true\n\n# year divisible by 200, not divisible by 400 in common year\n\"c30331f6-f9f6-4881-ad38-8ca8c12520c1\" = true\n"
  },
  {
    "path": "exercises/practice/leap/.meta/version",
    "content": "1.6.0\n"
  },
  {
    "path": "exercises/practice/leap/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/leap/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/leap/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/leap/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/leap/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/leap/src/main/kotlin/Leap.kt",
    "content": "data class Year(val todo: Nothing) {\n\n    // TODO: Implement proper constructor\n\n    val isLeap: Boolean = TODO(\"Implement this getter to complete the task\")\n}\n"
  },
  {
    "path": "exercises/practice/leap/src/test/kotlin/LeapTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertFalse\nimport kotlin.test.assertTrue\n\nclass LeapTest {\n    @Test\n    fun `not leap - not divisible by 4`() = assertYearIsCommon(2015)\n\n    @Ignore\n    @Test\n    fun `not leap - divisible by 2, not divisible by 4`() = assertYearIsCommon(1970)\n\n    @Ignore\n    @Test\n    fun `leap - divisible by 4, not divisible by 100`() = assertYearIsLeap(1996)\n\n    @Ignore\n    @Test\n    fun `leap - divisible by 4 and 5`() = assertYearIsLeap(1960)\n\n    @Ignore\n    @Test\n    fun `not leap - divisible by 100, not divisible by 400`() = assertYearIsCommon(2100)\n\n    @Ignore\n    @Test\n    fun `not leap - divisible by 100 but not by 3`() = assertYearIsCommon(1900)\n\n    @Ignore\n    @Test\n    fun `leap - divisible by 400`() = assertYearIsLeap(2000)\n\n    @Ignore\n    @Test\n    fun `leap - divisible by 400 but not by 125`() = assertYearIsLeap(2400)\n\n    @Ignore\n    @Test\n    fun `not leap - divisible by 200, not divisible by 400`() = assertYearIsCommon(1800)\n}\n\nprivate fun assertYearIsLeap(year: Int) = assertTrue(Year(year).isLeap)\n\nprivate fun assertYearIsCommon(year: Int) = assertFalse(Year(year).isLeap)\n"
  },
  {
    "path": "exercises/practice/linked-list/.docs/instructions.md",
    "content": "# Instructions\n\nYour team has decided to use a doubly linked list to represent each train route in the schedule.\nEach station along the train's route will be represented by a node in the linked list.\n\nYou don't need to worry about arrival and departure times at the stations.\nEach station will simply be represented by a number.\n\nRoutes can be extended, adding stations to the beginning or end of a route.\nThey can also be shortened by removing stations from the beginning or the end of a route.\n\nSometimes a station gets closed down, and in that case the station needs to be removed from the route, even if it is not at the beginning or end of the route.\n\nThe size of a route is measured not by how far the train travels, but by how many stations it stops at.\n\n~~~~exercism/note\nThe linked list is a fundamental data structure in computer science, often used in the implementation of other data structures.\nAs the name suggests, it is a list of nodes that are linked together.\nIt is a list of \"nodes\", where each node links to its neighbor or neighbors.\nIn a **singly linked list** each node links only to the node that follows it.\nIn a **doubly linked list** each node links to both the node that comes before, as well as the node that comes after.\n\nIf you want to dig deeper into linked lists, check out [this article][intro-linked-list] that explains it using nice drawings.\n\n[intro-linked-list]: https://medium.com/basecs/whats-a-linked-list-anyway-part-1-d8b7e6508b9d\n~~~~\n"
  },
  {
    "path": "exercises/practice/linked-list/.docs/introduction.md",
    "content": "# Introduction\n\nYou are working on a project to develop a train scheduling system for a busy railway network.\n\nYou've been asked to develop a prototype for the train routes in the scheduling system.\nEach route consists of a sequence of train stations that a given train stops at.\n"
  },
  {
    "path": "exercises/practice/linked-list/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/LinkedList.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/DequeTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/LinkedList.kt\"\n    ]\n  },\n  \"blurb\": \"Implement a doubly linked list.\",\n  \"source\": \"Classic computer science topic\"\n}\n"
  },
  {
    "path": "exercises/practice/linked-list/.meta/src/reference/kotlin/LinkedList.kt",
    "content": "class Deque<T> {\n    private var head: Element<T>? = null\n\n    fun push(value: T) {\n        if(head == null) {\n            head = Element(value)\n            head?.prev = head\n            head?.next = head\n        } else {\n            val oldTail = head?.prev\n            val tail = Element(value, prev = oldTail, next = head)\n            oldTail?.next = tail\n            head?.prev = tail\n        }\n\n    }\n\n    fun pop(): T? {\n        head = head?.prev\n        return shift()\n    }\n\n    fun unshift(value: T) {\n        push(value)\n        head = head?.prev\n    }\n\n    fun shift(): T? {\n        val value = head?.value\n        val newHead = head?.next\n        val newTail = head?.prev\n\n        if (newHead == head) {\n            head = null\n        } else {\n            newHead?.prev = newTail\n            newTail?.next = newHead\n            head = newHead\n        }\n\n        return value\n    }\n\n    private data class Element<T>(val value: T, var prev: Element<T>? = null, var next: Element<T>? = null)\n}\n"
  },
  {
    "path": "exercises/practice/linked-list/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/linked-list/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/linked-list/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/linked-list/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/linked-list/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/linked-list/src/main/kotlin/LinkedList.kt",
    "content": "class Deque<T> {\n\n    fun push(value: T) {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun pop(): T? {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun unshift(value: T) {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun shift(): T? {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/linked-list/src/test/kotlin/DequeTest.kt",
    "content": "import org.junit.Before\nimport org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass DequeTest {\n    private lateinit var subject: Deque<Int>\n\n    @Before\n    fun setUp() {\n        subject = Deque()\n    }\n\n\n    @Test\n    fun pushPop() {\n        subject.push(10)\n        subject.push(20)\n        assertEquals(20, subject.pop())\n        assertEquals(10, subject.pop())\n    }\n\n    @Ignore\n    @Test\n    fun pushShift() {\n        subject.push(10)\n        subject.push(20)\n        assertEquals(10, subject.shift())\n        assertEquals(20, subject.shift())\n    }\n\n    @Ignore\n    @Test\n    fun unshiftShift() {\n        subject.unshift(10)\n        subject.unshift(20)\n        assertEquals(20, subject.shift())\n        assertEquals(10, subject.shift())\n    }\n\n    @Ignore\n    @Test\n    fun unshiftPop() {\n        subject.unshift(10)\n        subject.unshift(20)\n        assertEquals(10, subject.pop())\n        assertEquals(20, subject.pop())\n    }\n\n    @Ignore\n    @Test\n    fun example() {\n        subject.push(10)\n        subject.push(20)\n        assertEquals(20, subject.pop())\n\n        subject.push(30)\n        assertEquals(10, subject.shift())\n\n        subject.unshift(40)\n        subject.push(50)\n        assertEquals(40, subject.shift())\n        assertEquals(50, subject.pop())\n        assertEquals(30, subject.shift())\n    }\n}\n"
  },
  {
    "path": "exercises/practice/list-ops/.docs/instructions.append.md",
    "content": "# Hints\n\nThe tests for this exercise require you to use extensions, a mechanism for adding new functionality to an existing class whose source you do not directly control without having to subclass it. To learn more about Kotlin's implementations of extensions, check out the [official documentation](https://kotlinlang.org/docs/reference/extensions.html#extensions).\n\nThe `customFoldLeft` and `customFoldRight` methods are \"fold\" functions, which is a concept well-known in the functional programming world, but less so in the object-oriented one. If you'd like more background information, check out this [fold](https://en.wikipedia.org/wiki/Fold_(higher-order_function)) page.\n"
  },
  {
    "path": "exercises/practice/list-ops/.docs/instructions.md",
    "content": "# Instructions\n\nImplement basic list operations.\n\nIn functional languages list operations like `length`, `map`, and `reduce` are very common.\nImplement a series of basic list operations, without using existing functions.\n\nThe precise number and names of the operations to be implemented will be track dependent to avoid conflicts with existing names, but the general operations you will implement include:\n\n- `append` (_given two lists, add all items in the second list to the end of the first list_);\n- `concatenate` (_given a series of lists, combine all items in all lists into one flattened list_);\n- `filter` (_given a predicate and a list, return the list of all items for which `predicate(item)` is True_);\n- `length` (_given a list, return the total number of items within it_);\n- `map` (_given a function and a list, return the list of the results of applying `function(item)` on all items_);\n- `foldl` (_given a function, a list, and initial accumulator, fold (reduce) each item into the accumulator from the left_);\n- `foldr` (_given a function, a list, and an initial accumulator, fold (reduce) each item into the accumulator from the right_);\n- `reverse` (_given a list, return a list with all the original items, but in reversed order_).\n\nNote, the ordering in which arguments are passed to the fold functions (`foldl`, `foldr`) is significant.\n"
  },
  {
    "path": "exercises/practice/list-ops/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"beatbrot\",\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"myronmarston\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/ListOps.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ListExtensionsTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/ListOps.kt\"\n    ]\n  },\n  \"blurb\": \"Implement basic list operations.\"\n}\n"
  },
  {
    "path": "exercises/practice/list-ops/.meta/src/reference/kotlin/ListOps.kt",
    "content": "fun <T> List<T>.customAppend(list: List<T>): List<T> {\n    val result = mutableListOf<T>()\n    result.addAll(this)\n    result.addAll(list)\n    return result\n}\n\nfun List<Any>.customConcat(): List<Any> {\n    val result = mutableListOf<Any>()\n    forEach { result.add(it) }\n    fun flatten(list: List<Any?>): List<Any> = list.flatMap {\n        if (it is List<Any?>) flatten(it)\n        else listOf(it)\n    }.filterNotNull()\n    return flatten(result)\n}\n\nfun <T> List<T>.customFilter(predicate: (T) -> Boolean): List<T> {\n    val result = mutableListOf<T>()\n    forEach { if (predicate(it)) { result.add(it) } }\n    return result\n}\n\nval List<Any>.customSize: Int\n    get() = size\n\nfun <T, U> List<T>.customMap(transform: (T) -> U): List<U> {\n    val result = mutableListOf<U>()\n    forEach { result.add(transform(it)) }\n    return result\n}\n\nfun <T, U> List<T>.customFoldLeft(initial: U, f: (U, T) -> U): U {\n    if (isEmpty()) return initial\n    return drop(1).customFoldLeft(f(initial, first()), f)\n}\n\nfun <T, U> List<T>.customFoldRight(initial: U, f: (T, U) -> U): U {\n    if (isEmpty()) return initial\n    return f(first(), drop(1).customFoldRight(initial, f))\n}\n\nfun <T> List<T>.customReverse(): List<T> {\n    val result = mutableListOf<T>()\n    forEach { result.add(0, it) }\n    return result\n}\n"
  },
  {
    "path": "exercises/practice/list-ops/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# empty lists\n\"485b9452-bf94-40f7-a3db-c3cf4850066a\" = true\n\n# list to empty list\n\"2c894696-b609-4569-b149-8672134d340a\" = true\n\n# non-empty lists\n\"71dcf5eb-73ae-4a0e-b744-a52ee387922f\" = true\n\n# empty list\n\"28444355-201b-4af2-a2f6-5550227bde21\" = true\n\n# list of lists\n\"331451c1-9573-42a1-9869-2d06e3b389a9\" = true\n\n# list of nested lists\n\"d6ecd72c-197f-40c3-89a4-aa1f45827e09\" = true\n\n# empty list\n\"0524fba8-3e0f-4531-ad2b-f7a43da86a16\" = true\n\n# non-empty list\n\"88494bd5-f520-4edb-8631-88e415b62d24\" = true\n\n# empty list\n\"1cf0b92d-8d96-41d5-9c21-7b3c37cb6aad\" = true\n\n# non-empty list\n\"d7b8d2d9-2d16-44c4-9a19-6e5f237cb71e\" = true\n\n# empty list\n\"c0bc8962-30e2-4bec-9ae4-668b8ecd75aa\" = true\n\n# non-empty list\n\"11e71a95-e78b-4909-b8e4-60cdcaec0e91\" = true\n\n# empty list\n\"613b20b7-1873-4070-a3a6-70ae5f50d7cc\" = true\n\n# direction independent function applied to non-empty list\n\"e56df3eb-9405-416a-b13a-aabb4c3b5194\" = true\n\n# direction dependent function applied to non-empty list\n\"d2cf5644-aee1-4dfc-9b88-06896676fe27\" = true\n\n# empty list\n\"aeb576b9-118e-4a57-a451-db49fac20fdc\" = true\n\n# direction independent function applied to non-empty list\n\"c4b64e58-313e-4c47-9c68-7764964efb8e\" = true\n\n# direction dependent function applied to non-empty list\n\"be396a53-c074-4db3-8dd6-f7ed003cce7c\" = true\n\n# empty list\n\"94231515-050e-4841-943d-d4488ab4ee30\" = true\n\n# non-empty list\n\"fcc03d1e-42e0-4712-b689-d54ad761f360\" = true\n\n# list of lists is not flattened\n\"40872990-b5b8-4cb8-9085-d91fc0d05d26\" = true\n"
  },
  {
    "path": "exercises/practice/list-ops/.meta/version",
    "content": "2.4.1\n"
  },
  {
    "path": "exercises/practice/list-ops/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/list-ops/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/list-ops/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/list-ops/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/list-ops/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/list-ops/src/main/kotlin/ListOps.kt",
    "content": "fun <T> List<T>.customAppend(list: List<T>): List<T> {\n    TODO(\"Implement this function to complete the task\")\n}\n\nfun List<Any>.customConcat(): List<Any> {\n    TODO(\"Implement this function to complete the task\")\n}\n\nfun <T> List<T>.customFilter(predicate: (T) -> Boolean): List<T> {\n    TODO(\"Implement this function to complete the task\")\n}\n\nval List<Any>.customSize: Int get() = TODO(\"Implement this getter to complete the task\")\n\nfun <T, U> List<T>.customMap(transform: (T) -> U): List<U> {\n    TODO(\"Implement this function to complete the task\")\n}\n\nfun <T, U> List<T>.customFoldLeft(initial: U, f: (U, T) -> U): U {\n    TODO(\"Implement this function to complete the task\")\n}\n\nfun <T, U> List<T>.customFoldRight(initial: U, f: (T, U) -> U): U {\n    TODO(\"Implement this function to complete the task\")\n}\n\nfun <T> List<T>.customReverse(): List<T> {\n    TODO(\"Implement this function to complete the task\")\n}\n"
  },
  {
    "path": "exercises/practice/list-ops/src/test/kotlin/ListExtensionsTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass ListExtensionsTest {\n\n    @Test\n    fun `append - empty lists`() =\n        assertEquals(\n            emptyList(),\n            emptyList<Int>().customAppend(emptyList())\n        )\n\n    @Ignore\n    @Test\n    fun `append - list to empty list`() =\n        assertEquals(\n            listOf('1', '2', '3', '4'),\n            emptyList<Char>().customAppend(listOf('1', '2', '3', '4'))\n        )\n\n    @Ignore\n    @Test\n    fun `append - non-empty lists`() =\n        assertEquals(\n            listOf(\"1\", \"2\", \"2\", \"3\", \"4\", \"5\"),\n            listOf(\"1\", \"2\").customAppend(listOf(\"2\", \"3\", \"4\", \"5\"))\n        )\n\n    @Ignore\n    @Test\n    fun `concatenate - empty list`() =\n        assertEquals(\n            emptyList<Char>(),\n            emptyList<Any>().customConcat()\n        )\n\n    @Ignore\n    @Test\n    fun `concatenate - list of lists`() =\n        assertEquals(\n            listOf('1', '2', '3', '4', '5', '6'),\n            listOf(\n                listOf('1', '2'),\n                listOf('3'),\n                emptyList(),\n                listOf('4', '5', '6')\n            ).customConcat()\n        )\n\n    @Ignore\n    @Test\n    fun `concatenate - list of nested lists`() =\n        assertEquals(\n            listOf('1', '2', '3', '4', '5', '6'),\n            listOf(\n                listOf(\n                    listOf('1'),\n                    listOf('2')\n                ),\n                listOf(\n                    listOf('3')\n                ),\n                listOf(\n                    emptyList()\n                ),\n                listOf(\n                    listOf('4', '5', '6')\n                )\n            ).customConcat()\n        )\n\n    @Ignore\n    @Test\n    fun `filter - empty list`() =\n        assertEquals(\n            emptyList(),\n            emptyList<Int>().customFilter { it % 2 == 1 })\n\n\n    @Ignore\n    @Test\n    fun `filter - non-empty list`() =\n        assertEquals(\n            listOf(1, 3, 5),\n            listOf(1, 2, 3, 5).customFilter { it % 2 == 1 })\n\n    @Ignore\n    @Test\n    fun `size - empty list`() = assertEquals(0, emptyList<Int>().customSize)\n\n    @Ignore\n    @Test\n    fun `size - non-empty list`() = assertEquals(4, listOf(\"one\", \"two\", \"three\", \"four\").customSize)\n\n    @Ignore\n    @Test\n    fun `map - empty list`() =\n        assertEquals(\n            emptyList(),\n            emptyList<Int>().customMap { it -> it + 1 })\n\n    @Ignore\n    @Test\n    fun `map - non-empty list`() =\n        assertEquals(\n            listOf(2, 4, 6, 8),\n            listOf(1, 3, 5, 7).customMap { it -> it + 1 })\n\n    @Ignore\n    @Test\n    fun `fold left - empty list`() =\n        assertEquals(\n            2.0,\n            emptyList<Int>().customFoldLeft(2.0, Double::times)\n        )\n\n    @Ignore\n    @Test\n    fun `fold left - direction independent function`() =\n        assertEquals(\n            15,\n            listOf(1, 2, 3, 4).customFoldLeft(5, Int::plus)\n        )\n\n    @Ignore\n    @Test\n    fun `fold left - direction dependent function`() =\n        assertEquals(\n            0,\n            listOf(2, 5).customFoldLeft(5, Int::div)\n        )\n\n    @Ignore\n    @Test\n    fun `fold right - empty list`() =\n        assertEquals(\n            2.0,\n            emptyList<Double>().customFoldRight(2.0, Double::times)\n        )\n\n    @Ignore\n    @Test\n    fun `fold right - direction independent function`() =\n        assertEquals(\n            15,\n            listOf(1, 2, 3, 4).customFoldRight(5, Int::plus)\n        )\n\n    @Ignore\n    @Test\n    fun `fold right - direction dependent function`() =\n        assertEquals(\n            2,\n            listOf(2, 5).customFoldRight(5, Int::div)\n        )\n\n    @Ignore\n    @Test\n    fun `reverse - empty list`() =\n        assertEquals(\n            emptyList(),\n            emptyList<Int>().customReverse()\n        )\n\n    @Ignore\n    @Test\n    fun `reverse - non-empty list`() =\n        assertEquals(\n            listOf('7', '5', '3', '1'),\n            listOf('1', '3', '5', '7').customReverse()\n        )\n\n    @Ignore\n    @Test\n    fun `reverse - list of lists`() =\n        assertEquals(\n            listOf(\n                listOf('4', '5', '6'),\n                emptyList<Char>(),\n                '3',\n                listOf('1', '2')\n            ),\n            listOf(\n                listOf('1', '2'),\n                '3',\n                emptyList<Char>(),\n                listOf('4', '5', '6')\n            ).customReverse()\n        )\n\n}\n"
  },
  {
    "path": "exercises/practice/luhn/.docs/instructions.md",
    "content": "# Instructions\n\nDetermine whether a credit card number is valid according to the [Luhn formula][luhn].\n\nThe number will be provided as a string.\n\n## Validating a number\n\nStrings of length 1 or less are not valid.\nSpaces are allowed in the input, but they should be stripped before checking.\nAll other non-digit characters are disallowed.\n\n### Example 1: valid credit card number\n\n```text\n4539 3195 0343 6467\n```\n\nThe first step of the Luhn algorithm is to double every second digit, starting from the right.\nWe will be doubling\n\n```text\n4539 3195 0343 6467\n↑ ↑  ↑ ↑  ↑ ↑  ↑ ↑  (double these)\n```\n\nIf doubling the number results in a number greater than 9 then subtract 9 from the product.\nThe results of our doubling:\n\n```text\n8569 6195 0383 3437\n```\n\nThen sum all of the digits:\n\n```text\n8+5+6+9+6+1+9+5+0+3+8+3+3+4+3+7 = 80\n```\n\nIf the sum is evenly divisible by 10, then the number is valid.\nThis number is valid!\n\n### Example 2: invalid credit card number\n\n```text\n8273 1232 7352 0569\n```\n\nDouble the second digits, starting from the right\n\n```text\n7253 2262 5312 0539\n```\n\nSum the digits\n\n```text\n7+2+5+3+2+2+6+2+5+3+1+2+0+5+3+9 = 57\n```\n\n57 is not evenly divisible by 10, so this number is not valid.\n\n[luhn]: https://en.wikipedia.org/wiki/Luhn_algorithm\n"
  },
  {
    "path": "exercises/practice/luhn/.docs/introduction.md",
    "content": "# Introduction\n\nAt the Global Verification Authority, you've just been entrusted with a critical assignment.\nAcross the city, from online purchases to secure logins, countless operations rely on the accuracy of numerical identifiers like credit card numbers, bank account numbers, transaction codes, and tracking IDs.\nThe Luhn algorithm is a simple checksum formula used to ensure these numbers are valid and error-free.\n\nA batch of identifiers has just arrived on your desk.\nAll of them must pass the Luhn test to ensure they're legitimate.\nIf any fail, they'll be flagged as invalid, preventing errors or fraud, such as incorrect transactions or unauthorized access.\n\nCan you ensure this is done right? The integrity of many services depends on you.\n"
  },
  {
    "path": "exercises/practice/luhn/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"enixander\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Luhn.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/LuhnTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Luhn.kt\"\n    ]\n  },\n  \"blurb\": \"Given a number determine whether or not it is valid per the Luhn formula.\",\n  \"source\": \"The Luhn Algorithm on Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Luhn_algorithm\"\n}\n"
  },
  {
    "path": "exercises/practice/luhn/.meta/src/reference/kotlin/Luhn.kt",
    "content": "object Luhn {\n\n    fun isValid(candidate: String): Boolean =\n            isValidCandidate(candidate) && checksum(number(candidate)) == 0\n\n    private fun isValidCandidate(candidate: String): Boolean =\n            candidate.filter(Char::isDigit).length > 1 &&\n            candidate.all { it.isDigit() || Character.isSpaceChar(it) }\n\n    private fun number(candidate: String) = candidate.filter(Char::isDigit).toLong()\n\n    private fun checksum(number: Long) = addends(number).sum() % 10\n\n    private fun addends(number: Long): List<Int> = digits(number).withIndex().reversed()\n            .map { if (isOdd(it.index)) dbl(it.value) else it.value }\n\n    private fun digits(n: Long): List<Int> = when (n) {\n        0L -> emptyList()\n        else -> listOf((n % 10).toInt()) + digits(n / 10)\n    }\n\n    private fun dbl(n: Int): Int {\n        val dbled = n * 2\n        return if (dbled > 9) dbled - 9 else dbled\n    }\n\n    private fun isOdd(i: Int) = i % 2 == 1\n\n}\n"
  },
  {
    "path": "exercises/practice/luhn/.meta/tests.toml",
    "content": "# This is an auto-generated file.\n#\n# Regenerating this file via `configlet sync` will:\n# - Recreate every `description` key/value pair\n# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications\n# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)\n# - Preserve any other key/value pair\n#\n# As user-added comments (using the # character) will be removed when this file\n# is regenerated, comments can be added via a `comment` key.\n\n[792a7082-feb7-48c7-b88b-bbfec160865e]\ndescription = \"single digit strings can not be valid\"\n\n[698a7924-64d4-4d89-8daa-32e1aadc271e]\ndescription = \"a single zero is invalid\"\n\n[73c2f62b-9b10-4c9f-9a04-83cee7367965]\ndescription = \"a simple valid SIN that remains valid if reversed\"\n\n[9369092e-b095-439f-948d-498bd076be11]\ndescription = \"a simple valid SIN that becomes invalid if reversed\"\n\n[8f9f2350-1faf-4008-ba84-85cbb93ffeca]\ndescription = \"a valid Canadian SIN\"\n\n[1cdcf269-6560-44fc-91f6-5819a7548737]\ndescription = \"invalid Canadian SIN\"\n\n[656c48c1-34e8-4e60-9a5a-aad8a367810a]\ndescription = \"invalid credit card\"\n\n[20e67fad-2121-43ed-99a8-14b5b856adb9]\ndescription = \"invalid long number with an even remainder\"\n\n[ad2a0c5f-84ed-4e5b-95da-6011d6f4f0aa]\ndescription = \"valid number with an even number of digits\"\n\n[ef081c06-a41f-4761-8492-385e13c8202d]\ndescription = \"valid number with an odd number of spaces\"\n\n[bef66f64-6100-4cbb-8f94-4c9713c5e5b2]\ndescription = \"valid strings with a non-digit added at the end become invalid\"\n\n[2177e225-9ce7-40f6-b55d-fa420e62938e]\ndescription = \"valid strings with punctuation included become invalid\"\n\n[ebf04f27-9698-45e1-9afe-7e0851d0fe8d]\ndescription = \"valid strings with symbols included become invalid\"\n\n[08195c5e-ce7f-422c-a5eb-3e45fece68ba]\ndescription = \"single zero with space is invalid\"\n\n[12e63a3c-f866-4a79-8c14-b359fc386091]\ndescription = \"more than a single zero is valid\"\n\n[ab56fa80-5de8-4735-8a4a-14dae588663e]\ndescription = \"input digit 9 is correctly converted to output digit 9\"\n\n[8a7c0e24-85ea-4154-9cf1-c2db90eabc08]\ndescription = \"valid luhn with an odd number of digits and non zero first digit\"\n\n[39a06a5a-5bad-4e0f-b215-b042d46209b1]\ndescription = \"using ascii value for non-doubled non-digit isn't allowed\"\n\n[f94cf191-a62f-4868-bc72-7253114aa157]\ndescription = \"using ascii value for doubled non-digit isn't allowed\"\n"
  },
  {
    "path": "exercises/practice/luhn/.meta/version",
    "content": "1.6.1\n"
  },
  {
    "path": "exercises/practice/luhn/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/luhn/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/luhn/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/luhn/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/luhn/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/luhn/src/main/kotlin/Luhn.kt",
    "content": "object Luhn {\n\n    fun isValid(candidate: String): Boolean {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/luhn/src/test/kotlin/LuhnTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertFalse\nimport kotlin.test.assertTrue\n\nclass LuhnTest {\n\n    @Test\n    fun `invalid - single digit`() = assertInvalid(\"1\")\n\n    @Ignore\n    @Test\n    fun `invalid - a single zero`() = assertInvalid(\"0\")\n\n    @Ignore\n    @Test\n    fun `valid - simple reversable`() = assertValid(\"059\")\n\n    @Ignore\n    @Test\n    fun `valid - simple unreversable`() = assertValid(\"59\")\n\n    @Ignore\n    @Test\n    fun `valid - Canadian`() = assertValid(\"055 444 285\")\n\n    @Ignore\n    @Test\n    fun `invalid - Canadian`() = assertInvalid(\"055 444 286\")\n\n    @Ignore\n    @Test\n    fun `invalid - credit card`() = assertInvalid(\"8273 1232 7352 0569\")\n\n    @Ignore\n    @Test\n    fun `valid - even amount of digits`() = assertValid(\"095 245 88\")\n\n    @Ignore\n    @Test\n    fun `valid - odd amount of spaces`() = assertValid(\"234 567 891 234\")\n\n    @Ignore\n    @Test\n    fun `invalid - non-digit at the end of valid`() = assertInvalid(\"059a\")\n\n    @Ignore\n    @Test\n    fun `invalid - punctuation in valid`() = assertInvalid(\"055-444-285\")\n\n    @Ignore\n    @Test\n    fun `invalid - symbols in valid`() = assertInvalid(\"055# 444$ 285\")\n\n    @Ignore\n    @Test\n    fun `invalid - single zero with space`() = assertInvalid(\" 0\")\n\n    @Ignore\n    @Test\n    fun `valid - many zeros`() = assertValid(\"0000 0\")\n\n    @Ignore\n    @Test\n    fun `valid - input digit 9`() = assertValid(\"091\")\n\n    @Ignore\n    @Test\n    fun `valid | valid luhn with an odd number of digits and non zero first digit`() = assertValid(\"109\")\n\n    /**\n     * Convert non-digits to their ascii values and then offset them by 48\n     * sometimes accidentally declare an invalid string to be valid.\n     * This test is designed to avoid that solution.\n     */\n    @Ignore\n    @Test\n    fun `invalid - ascii value for non-doubled non-digit in the middle`() = assertInvalid(\"055b 444 285\")\n\n    /**\n     * Convert non-digits to their ascii values and then offset them by 48\n     * sometimes accidentally declare an invalid string to be valid.\n     * This test is designed to avoid that solution.\n     */\n    @Ignore\n    @Test\n    fun `invalid - ascii value for non-doubled non-digit at the start`() = assertInvalid(\":9\")\n}\n\nprivate fun assertValid(value: String) = assertTrue(Luhn.isValid(value))\nprivate fun assertInvalid(value: String) = assertFalse(Luhn.isValid(value))\n"
  },
  {
    "path": "exercises/practice/matching-brackets/.docs/instructions.md",
    "content": "# Instructions\n\nGiven a string containing brackets `[]`, braces `{}`, parentheses `()`, or any combination thereof, verify that any and all pairs are matched and nested correctly.\nAny other characters should be ignored.\nFor example, `\"{what is (42)}?\"` is balanced and `\"[text}\"` is not.\n"
  },
  {
    "path": "exercises/practice/matching-brackets/.docs/introduction.md",
    "content": "# Introduction\n\nYou're given the opportunity to write software for the Bracketeer™, an ancient but powerful mainframe.\nThe software that runs on it is written in a proprietary language.\nMuch of its syntax is familiar, but you notice _lots_ of brackets, braces and parentheses.\nDespite the Bracketeer™ being powerful, it lacks flexibility.\nIf the source code has any unbalanced brackets, braces or parentheses, the Bracketeer™ crashes and must be rebooted.\nTo 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™.\n"
  },
  {
    "path": "exercises/practice/matching-brackets/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"geoand\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"enixander\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/MatchingBrackets.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/MatchingBracketsTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/MatchingBrackets.kt\"\n    ]\n  },\n  \"blurb\": \"Make sure the brackets and braces all match.\",\n  \"source\": \"Ginna Baker\"\n}\n"
  },
  {
    "path": "exercises/practice/matching-brackets/.meta/src/reference/kotlin/MatchingBrackets.kt",
    "content": "import java.util.*\nimport java.util.Collections.asLifoQueue\n\nobject MatchingBrackets {\n\n    private val CLOSING_TO_OPENING_MAP = mapOf(\n             '}' to '{',\n             ')' to '(',\n             ']' to '['\n    )\n\n    private val OPENING_BRACKETS = CLOSING_TO_OPENING_MAP.values\n    private val CLOSING_BRACKETS = CLOSING_TO_OPENING_MAP.keys\n\n    private val ALL_BRACKET = OPENING_BRACKETS + CLOSING_BRACKETS\n\n    fun isValid(input: String): Boolean {\n        val onlyBracketChars = input.filter { it.isBracket() }.toList()\n\n        return isValidRec(onlyBracketChars, asLifoQueue(ArrayDeque<Char>()))\n    }\n\n    private tailrec fun isValidRec(bracketChars: List<Char>, stack: Queue<Char>): Boolean {\n        if(bracketChars.isEmpty()) {\n            return stack.isEmpty()\n        }\n\n        val firstChar = bracketChars.first()\n        if(firstChar.isOpeningBracket()) {\n            return isValidRec(bracketChars.tail(), stack.push(firstChar))\n        }\n        else {\n            val stackHead = stack.poll() ?: return false\n\n            val isMatch = firstChar.matchingOpeningBracket() == stackHead\n\n            return if(isMatch) isValidRec(bracketChars.tail(), stack) else false\n        }\n    }\n\n    fun Char.isBracket() = this in ALL_BRACKET\n\n    fun Char.isOpeningBracket() = this in OPENING_BRACKETS\n\n    fun Char.matchingOpeningBracket() = CLOSING_TO_OPENING_MAP[this] ?: throw IllegalArgumentException(\"Char ${this} is not a closing bracket\")\n\n}\n\nfun <T> List<T>.tail() = this.subList(1, this.size)\n\nfun <T> Queue<T>.push(element: T): Queue<T> {\n    this.add(element)\n    return this\n}\n"
  },
  {
    "path": "exercises/practice/matching-brackets/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# paired square brackets\n\"81ec11da-38dd-442a-bcf9-3de7754609a5\" = true\n\n# empty string\n\"287f0167-ac60-4b64-8452-a0aa8f4e5238\" = true\n\n# unpaired brackets\n\"6c3615a3-df01-4130-a731-8ef5f5d78dac\" = true\n\n# wrong ordered brackets\n\"9d414171-9b98-4cac-a4e5-941039a97a77\" = true\n\n# wrong closing bracket\n\"f0f97c94-a149-4736-bc61-f2c5148ffb85\" = true\n\n# paired with whitespace\n\"754468e0-4696-4582-a30e-534d47d69756\" = true\n\n# partially paired brackets\n\"ba84f6ee-8164-434a-9c3e-b02c7f8e8545\" = true\n\n# simple nested brackets\n\"3c86c897-5ff3-4a2b-ad9b-47ac3a30651d\" = true\n\n# several paired brackets\n\"2d137f2c-a19e-4993-9830-83967a2d4726\" = true\n\n# paired and nested brackets\n\"2e1f7b56-c137-4c92-9781-958638885a44\" = true\n\n# unopened closing brackets\n\"84f6233b-e0f7-4077-8966-8085d295c19b\" = true\n\n# unpaired and nested brackets\n\"9b18c67d-7595-4982-b2c5-4cb949745d49\" = true\n\n# paired and wrong nested brackets\n\"a0205e34-c2ac-49e6-a88a-899508d7d68e\" = true\n\n# paired and incomplete brackets\n\"ef47c21b-bcfd-4998-844c-7ad5daad90a8\" = true\n\n# too many closing brackets\n\"a4675a40-a8be-4fc2-bc47-2a282ce6edbe\" = true\n\n# math expression\n\"99255f93-261b-4435-a352-02bdecc9bdf2\" = true\n\n# complex latex expression\n\"8e357d79-f302-469a-8515-2561877256a1\" = true\n"
  },
  {
    "path": "exercises/practice/matching-brackets/.meta/version",
    "content": "2.0.0\n"
  },
  {
    "path": "exercises/practice/matching-brackets/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/matching-brackets/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/matching-brackets/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/matching-brackets/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/matching-brackets/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/matching-brackets/src/main/kotlin/MatchingBrackets.kt",
    "content": "object MatchingBrackets {\n\n    fun isValid(input: String): Boolean {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/matching-brackets/src/test/kotlin/MatchingBracketsTest.kt",
    "content": "\nimport org.junit.Test\nimport org.junit.Ignore\nimport org.junit.runner.RunWith\nimport org.junit.runners.Parameterized\nimport kotlin.test.assertEquals\n\n@RunWith(Parameterized::class)\nclass MatchingBracketsTest(val input: String, val expectedOutput: Boolean) {\n\n    companion object {\n        @JvmStatic\n        @Parameterized.Parameters(name = \"{index}: bracket({0})={1}\")\n        fun data() = listOf(\n                arrayOf(\"[]\", true),\n                arrayOf(\"\", true),\n                arrayOf(\"[[\", false),\n                arrayOf(\"}{\", false),\n                arrayOf(\"{]\", false),\n                arrayOf(\"{ }\", true),\n                arrayOf(\"{[])\", false),\n                arrayOf(\"{[]}\", true),\n                arrayOf(\"{}[]\", true),\n                arrayOf(\"([{}({}[])])\", true),\n                arrayOf(\"{[)][]}\", false),\n                arrayOf(\"([{])\", false),\n                arrayOf(\"[({]})\", false),\n                arrayOf(\"{}[\", false),\n                arrayOf(\"[]]\", false),\n                arrayOf(\"(((185 + 223.85) * 15) - 543)/2\", true),\n                arrayOf(\"\\\\\\\\left(\\\\\\\\begin{array}{cc} \\\\\\\\frac{1}{3} & x\\\\\\\\\\\\\\\\ \\\\\\\\mathrm{e}^{x} &... x^2 \\\\\\\\end{array}\\\\\\\\right)\", true)\n        )\n    }\n\n    @Test\n    fun test() {\n        assertEquals(expectedOutput, MatchingBrackets.isValid(input))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/matrix/.docs/instructions.md",
    "content": "# Instructions\n\nGiven a string representing a matrix of numbers, return the rows and columns of that matrix.\n\nSo given a string with embedded newlines like:\n\n```text\n9 8 7\n5 3 2\n6 6 7\n```\n\nrepresenting this matrix:\n\n```text\n    1  2  3\n  |---------\n1 | 9  8  7\n2 | 5  3  2\n3 | 6  6  7\n```\n\nyour code should be able to spit out:\n\n- A list of the rows, reading each row left-to-right while moving top-to-bottom across the rows,\n- A list of the columns, reading each column top-to-bottom while moving from left-to-right.\n\nThe rows for our example matrix:\n\n- 9, 8, 7\n- 5, 3, 2\n- 6, 6, 7\n\nAnd its columns:\n\n- 9, 5, 6\n- 8, 3, 6\n- 7, 2, 7\n"
  },
  {
    "path": "exercises/practice/matrix/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"SunCatMC\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Matrix.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/MatrixTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Matrix.kt\"\n    ]\n  },\n  \"blurb\": \"Given a string representing a matrix of numbers, return the rows and columns of that matrix.\",\n  \"source\": \"Exercise by the JumpstartLab team for students at The Turing School of Software and Design.\",\n  \"source_url\": \"https://turing.edu\"\n}\n"
  },
  {
    "path": "exercises/practice/matrix/.meta/src/reference/kotlin/Matrix.kt",
    "content": "class Matrix(private val matrixAsString: String) {\n\n    private val matrix: List<List<Int>> = matrixAsString\n            .split(\"\\n\")\n            .map { column ->\n                column.trim().split(Regex(\" +\"))\n                        .map { cell -> cell.toInt() }\n            }\n\n    fun column(colNr: Int): List<Int> = matrix.indices.map { matrix[it][colNr - 1] }\n\n    fun row(rowNr: Int): List<Int> = matrix[rowNr - 1]\n}\n"
  },
  {
    "path": "exercises/practice/matrix/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# extract row from one number matrix\n\"ca733dab-9d85-4065-9ef6-a880a951dafd\" = true\n\n# can extract row\n\"5c93ec93-80e1-4268-9fc2-63bc7d23385c\" = true\n\n# extract row where numbers have different widths\n\"2f1aad89-ad0f-4bd2-9919-99a8bff0305a\" = true\n\n# can extract row from non-square matrix with no corresponding column\n\"68f7f6ba-57e2-4e87-82d0-ad09889b5204\" = true\n\n# extract column from one number matrix\n\"e8c74391-c93b-4aed-8bfe-f3c9beb89ebb\" = true\n\n# can extract column\n\"7136bdbd-b3dc-48c4-a10c-8230976d3727\" = true\n\n# can extract column from non-square matrix with no corresponding row\n\"ad64f8d7-bba6-4182-8adf-0c14de3d0eca\" = true\n\n# extract column where numbers have different widths\n\"9eddfa5c-8474-440e-ae0a-f018c2a0dd89\" = true\n"
  },
  {
    "path": "exercises/practice/matrix/.meta/version",
    "content": "1.3.0\n"
  },
  {
    "path": "exercises/practice/matrix/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/matrix/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/matrix/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/matrix/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/matrix/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/matrix/src/main/kotlin/Matrix.kt",
    "content": "class Matrix(private val matrixAsString: String) {\n\n    fun column(colNr: Int): List<Int> {\n        TODO(\"Implement this to complete the task\")\n    }\n\n    fun row(rowNr: Int): List<Int> {\n        TODO(\"Implement this to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/matrix/src/test/kotlin/MatrixTest.kt",
    "content": "import kotlin.test.Ignore\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\n\nclass MatrixTest {\n\n    @Test\n    fun `extract row from one number matrix`() {\n        val matrixAsString = \"1\"\n        val rowIndex = 1\n        val expectedRow = listOf(1)\n        assertEquals(expectedRow, Matrix(matrixAsString).row(rowIndex))\n    }\n\n    @Ignore\n    @Test\n    fun `extract row from matrix`() {\n        val matrixAsString = \"1 2\\n3 4\"\n        val rowIndex = 2\n        val expectedRow = listOf(3, 4)\n        assertEquals(expectedRow, Matrix(matrixAsString).row(rowIndex))\n    }\n\n    @Ignore\n    @Test\n    fun `extract row from diff widths matrix`() {\n        val matrixAsString = \"1 2\\n10 20\"\n        val rowIndex = 2\n        val expectedRow = listOf(10, 20)\n        assertEquals(expectedRow, Matrix(matrixAsString).row(rowIndex))\n    }\n\n    @Ignore\n    @Test\n    fun `extract row from non square matrix`() {\n        val matrixAsString = \"\"\"\n            1 2 3\n            4 5 6\n            7 8 9\n            8 7 6\n            \"\"\".trimIndent()\n        val rowIndex = 4\n        val expectedRow = listOf(8, 7, 6)\n        assertEquals(expectedRow, Matrix(matrixAsString).row(rowIndex))\n    }\n\n    @Ignore\n    @Test\n    fun `extract column from one number matrix`() {\n        val matrixAsString = \"1\"\n        val columnIndex = 1\n        val expectedColumn = listOf(1)\n        assertEquals(expectedColumn, Matrix(matrixAsString).column(columnIndex))\n    }\n\n    @Ignore\n    @Test\n    fun `extract column matrix`() {\n        val matrixAsString = \"\"\"\n            1 2 3\n            4 5 6\n            7 8 9\n            \"\"\".trimIndent()\n        val columnIndex = 3\n        val expectedColumn = listOf(3, 6, 9)\n        assertEquals(expectedColumn, Matrix(matrixAsString).column(columnIndex))\n    }\n\n    @Ignore\n    @Test\n    fun `extract column from non square matrix`() {\n        val matrixAsString = \"\"\"\n            1 2 3 4\n            5 6 7 8\n            9 8 7 6\n            \"\"\".trimIndent()\n        val columnIndex = 4\n        val expectedColumn = listOf(4, 8, 6)\n        assertEquals(expectedColumn, Matrix(matrixAsString).column(columnIndex))\n    }\n\n    @Ignore\n    @Test\n    fun `extract column from diff widths matrix`() {\n        val matrixAsString = \"\"\"\n            89 1903   3\n            18    3   1\n             9    4 800\n            \"\"\".replace(Regex(\" +\"), \" \").trimIndent()\n        val columnIndex = 2\n        val expectedColumn = listOf(1903, 3, 4)\n        assertEquals(expectedColumn, Matrix(matrixAsString).column(columnIndex))\n    }\n}\n"
  },
  {
    "path": "exercises/practice/meetup/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to find the exact date of a meetup, given a month, year, weekday and week.\n\nThere are five week values to consider: `first`, `second`, `third`, `fourth`, `last`, `teenth`.\n\nFor example, you might be asked to find the date for the meetup on the first Monday in January 2018 (January 1, 2018).\n\nSimilarly, you might be asked to find:\n\n- the third Tuesday of August 2019 (August 20, 2019)\n- the teenth Wednesday of May 2020 (May 13, 2020)\n- the fourth Sunday of July 2021 (July 25, 2021)\n- the last Thursday of November 2022 (November 24, 2022)\n- the teenth Saturday of August 1953 (August 15, 1953)\n\n## Teenth\n\nThe teenth week refers to the seven days in a month that end in '-teenth' (13th, 14th, 15th, 16th, 17th, 18th and 19th).\n\nIf asked to find the teenth Saturday of August, 1953, we check its calendar:\n\n```plaintext\n    August 1953\nSu Mo Tu We Th Fr Sa\n                   1\n 2  3  4  5  6  7  8\n 9 10 11 12 13 14 15\n16 17 18 19 20 21 22\n23 24 25 26 27 28 29\n30 31\n```\n\nFrom this we find that the teenth Saturday is August 15, 1953.\n"
  },
  {
    "path": "exercises/practice/meetup/.docs/introduction.md",
    "content": "# Introduction\n\nEvery month, your partner meets up with their best friend.\nBoth of them have very busy schedules, making it challenging to find a suitable date!\nGiven your own busy schedule, your partner always double-checks potential meetup dates with you:\n\n- \"Can I meet up on the first Friday of next month?\"\n- \"What about the third Wednesday?\"\n- \"Maybe the last Sunday?\"\n\nIn this month's call, your partner asked you this question:\n\n- \"I'd like to meet up on the teenth Thursday; is that okay?\"\n\nConfused, you ask what a \"teenth\" day is.\nYour partner explains that a teenth day, a concept they made up, refers to the days in a month that end in '-teenth':\n\n- 13th (thirteenth)\n- 14th (fourteenth)\n- 15th (fifteenth)\n- 16th (sixteenth)\n- 17th (seventeenth)\n- 18th (eighteenth)\n- 19th (nineteenth)\n\nAs there are also seven weekdays, it is guaranteed that each day of the week has _exactly one_ teenth day each month.\n\nNow that you understand the concept of a teenth day, you check your calendar.\nYou don't have anything planned on the teenth Thursday, so you happily confirm the date with your partner.\n"
  },
  {
    "path": "exercises/practice/meetup/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Meetup.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/MeetupTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Meetup.kt\"\n    ]\n  },\n  \"blurb\": \"Calculate the date of meetups.\",\n  \"source\": \"Jeremy Hinegardner mentioned a Boulder meetup that happens on the Wednesteenth of every month\"\n}\n"
  },
  {
    "path": "exercises/practice/meetup/.meta/src/reference/kotlin/Meetup.kt",
    "content": "import java.time.DayOfWeek\nimport java.time.LocalDate\n\nclass Meetup(monthOfYear: Int, year: Int) {\n\n    private val startOfMonth: LocalDate = LocalDate.of(year, monthOfYear, 1)\n\n    fun day(dayOfWeek: DayOfWeek, schedule: MeetupSchedule): LocalDate {\n        var result = cycleToNext(dayOfWeek, startOfMonth)\n\n        @Suppress(\"NON_EXHAUSTIVE_WHEN\")\n        when (schedule) {\n            MeetupSchedule.SECOND -> result = result.plusWeeks(1)\n            MeetupSchedule.THIRD  -> result = result.plusWeeks(2)\n            MeetupSchedule.FOURTH -> result = result.plusWeeks(3)\n            MeetupSchedule.LAST   -> result = cycleToPrev(dayOfWeek, startOfMonth.plusMonths(1).minusDays(1))\n            MeetupSchedule.TEENTH -> {\n                while (result.dayOfMonth < 13) result = result.plusWeeks(1)\n            }\n\n            // TODO: This may need to be fixed in the future as Kotlin 1.7+ may raise a compilation error for\n            //  non-exhaustive when blocks.\n        }\n\n        return result\n    }\n\n    private fun cycleToPrev(dayOfWeek: DayOfWeek, current: LocalDate): LocalDate {\n        var result = current\n\n        while (result.dayOfWeek != dayOfWeek) {\n            result = result.minusDays(1)\n        }\n\n        return result\n    }\n\n    private fun cycleToNext(dayOfWeek: DayOfWeek, current: LocalDate): LocalDate {\n        var result = current\n\n        while (result.dayOfWeek != dayOfWeek) {\n            result = result.plusDays(1)\n        }\n\n        return result\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/meetup/.meta/src/reference/kotlin/MeetupSchedule.kt",
    "content": "enum class MeetupSchedule {\n\n    FIRST, SECOND, THIRD, FOURTH, LAST, TEENTH\n\n}\n"
  },
  {
    "path": "exercises/practice/meetup/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# monteenth of May 2013\n\"d7f8eadd-d4fc-46ee-8a20-e97bd3fd01c8\" = true\n\n# monteenth of August 2013\n\"f78373d1-cd53-4a7f-9d37-e15bf8a456b4\" = true\n\n# monteenth of September 2013\n\"8c78bea7-a116-425b-9c6b-c9898266d92a\" = true\n\n# tuesteenth of March 2013\n\"cfef881b-9dc9-4d0b-8de4-82d0f39fc271\" = true\n\n# tuesteenth of April 2013\n\"69048961-3b00-41f9-97ee-eb6d83a8e92b\" = true\n\n# tuesteenth of August 2013\n\"d30bade8-3622-466a-b7be-587414e0caa6\" = true\n\n# wednesteenth of January 2013\n\"8db4b58b-92f3-4687-867b-82ee1a04f851\" = true\n\n# wednesteenth of February 2013\n\"6c27a2a2-28f8-487f-ae81-35d08c4664f7\" = true\n\n# wednesteenth of June 2013\n\"008a8674-1958-45b5-b8e6-c2c9960d973a\" = true\n\n# thursteenth of May 2013\n\"e4abd5e3-57cb-4091-8420-d97e955c0dbd\" = true\n\n# thursteenth of June 2013\n\"85da0b0f-eace-4297-a6dd-63588d5055b4\" = true\n\n# thursteenth of September 2013\n\"ecf64f9b-8413-489b-bf6e-128045f70bcc\" = true\n\n# friteenth of April 2013\n\"ac4e180c-7d0a-4d3d-b05f-f564ebb584ca\" = true\n\n# friteenth of August 2013\n\"b79101c7-83ad-4f8f-8ec8-591683296315\" = true\n\n# friteenth of September 2013\n\"6ed38b9f-0072-4901-bd97-7c8b8b0ef1b8\" = true\n\n# saturteenth of February 2013\n\"dfae03ed-9610-47de-a632-655ab01e1e7c\" = true\n\n# saturteenth of April 2013\n\"ec02e3e1-fc72-4a3c-872f-a53fa8ab358e\" = true\n\n# saturteenth of October 2013\n\"d983094b-7259-4195-b84e-5d09578c89d9\" = true\n\n# sunteenth of May 2013\n\"d84a2a2e-f745-443a-9368-30051be60c2e\" = true\n\n# sunteenth of June 2013\n\"0e64bc53-92a3-4f61-85b2-0b7168c7ce5a\" = true\n\n# sunteenth of October 2013\n\"de87652c-185e-4854-b3ae-04cf6150eead\" = true\n\n# first Monday of March 2013\n\"2cbfd0f5-ba3a-46da-a8cc-0fe4966d3411\" = true\n\n# first Monday of April 2013\n\"a6168c7c-ed95-4bb3-8f92-c72575fc64b0\" = true\n\n# first Tuesday of May 2013\n\"1bfc620f-1c54-4bbd-931f-4a1cd1036c20\" = true\n\n# first Tuesday of June 2013\n\"12959c10-7362-4ca0-a048-50cf1c06e3e2\" = true\n\n# first Wednesday of July 2013\n\"1033dc66-8d0b-48a1-90cb-270703d59d1d\" = true\n\n# first Wednesday of August 2013\n\"b89185b9-2f32-46f4-a602-de20b09058f6\" = true\n\n# first Thursday of September 2013\n\"53aedc4d-b2c8-4dfb-abf7-a8dc9cdceed5\" = true\n\n# first Thursday of October 2013\n\"b420a7e3-a94c-4226-870a-9eb3a92647f0\" = true\n\n# first Friday of November 2013\n\"61df3270-28b4-4713-bee2-566fa27302ca\" = true\n\n# first Friday of December 2013\n\"cad33d4d-595c-412f-85cf-3874c6e07abf\" = true\n\n# first Saturday of January 2013\n\"a2869b52-5bba-44f0-a863-07bd1f67eadb\" = true\n\n# first Saturday of February 2013\n\"3585315a-d0db-4ea1-822e-0f22e2a645f5\" = true\n\n# first Sunday of March 2013\n\"c49e9bd9-8ccf-4cf2-947a-0ccd4e4f10b1\" = true\n\n# first Sunday of April 2013\n\"1513328b-df53-4714-8677-df68c4f9366c\" = true\n\n# second Monday of March 2013\n\"49e083af-47ec-4018-b807-62ef411efed7\" = true\n\n# second Monday of April 2013\n\"6cb79a73-38fe-4475-9101-9eec36cf79e5\" = true\n\n# second Tuesday of May 2013\n\"4c39b594-af7e-4445-aa03-bf4f8effd9a1\" = true\n\n# second Tuesday of June 2013\n\"41b32c34-2e39-40e3-b790-93539aaeb6dd\" = true\n\n# second Wednesday of July 2013\n\"90a160c5-b5d9-4831-927f-63a78b17843d\" = true\n\n# second Wednesday of August 2013\n\"23b98ce7-8dd5-41a1-9310-ef27209741cb\" = true\n\n# second Thursday of September 2013\n\"447f1960-27ca-4729-bc3f-f36043f43ed0\" = true\n\n# second Thursday of October 2013\n\"c9aa2687-300c-4e79-86ca-077849a81bde\" = true\n\n# second Friday of November 2013\n\"a7e11ef3-6625-4134-acda-3e7195421c09\" = true\n\n# second Friday of December 2013\n\"8b420e5f-9290-4106-b5ae-022f3e2a3e41\" = true\n\n# second Saturday of January 2013\n\"80631afc-fc11-4546-8b5f-c12aaeb72b4f\" = true\n\n# second Saturday of February 2013\n\"e34d43ac-f470-44c2-aa5f-e97b78ecaf83\" = true\n\n# second Sunday of March 2013\n\"a57d59fd-1023-47ad-b0df-a6feb21b44fc\" = true\n\n# second Sunday of April 2013\n\"a829a8b0-abdd-4ad1-b66c-5560d843c91a\" = true\n\n# third Monday of March 2013\n\"501a8a77-6038-4fc0-b74c-33634906c29d\" = true\n\n# third Monday of April 2013\n\"49e4516e-cf32-4a58-8bbc-494b7e851c92\" = true\n\n# third Tuesday of May 2013\n\"4db61095-f7c7-493c-85f1-9996ad3012c7\" = true\n\n# third Tuesday of June 2013\n\"714fc2e3-58d0-4b91-90fd-61eefd2892c0\" = true\n\n# third Wednesday of July 2013\n\"b08a051a-2c80-445b-9b0e-524171a166d1\" = true\n\n# third Wednesday of August 2013\n\"80bb9eff-3905-4c61-8dc9-bb03016d8ff8\" = true\n\n# third Thursday of September 2013\n\"fa52a299-f77f-4784-b290-ba9189fbd9c9\" = true\n\n# third Thursday of October 2013\n\"f74b1bc6-cc5c-4bf1-ba69-c554a969eb38\" = true\n\n# third Friday of November 2013\n\"8900f3b0-801a-466b-a866-f42d64667abd\" = true\n\n# third Friday of December 2013\n\"538ac405-a091-4314-9ccd-920c4e38e85e\" = true\n\n# third Saturday of January 2013\n\"244db35c-2716-4fa0-88ce-afd58e5cf910\" = true\n\n# third Saturday of February 2013\n\"dd28544f-f8fa-4f06-9bcd-0ad46ce68e9e\" = true\n\n# third Sunday of March 2013\n\"be71dcc6-00d2-4b53-a369-cbfae55b312f\" = true\n\n# third Sunday of April 2013\n\"b7d2da84-4290-4ee6-a618-ee124ae78be7\" = true\n\n# fourth Monday of March 2013\n\"4276dc06-a1bd-4fc2-b6c2-625fee90bc88\" = true\n\n# fourth Monday of April 2013\n\"ddbd7976-2deb-4250-8a38-925ac1a8e9a2\" = true\n\n# fourth Tuesday of May 2013\n\"eb714ef4-1656-47cc-913c-844dba4ebddd\" = true\n\n# fourth Tuesday of June 2013\n\"16648435-7937-4d2d-b118-c3e38fd084bd\" = true\n\n# fourth Wednesday of July 2013\n\"de062bdc-9484-437a-a8c5-5253c6f6785a\" = true\n\n# fourth Wednesday of August 2013\n\"c2ce6821-169c-4832-8d37-690ef5d9514a\" = true\n\n# fourth Thursday of September 2013\n\"d462c631-2894-4391-a8e3-dbb98b7a7303\" = true\n\n# fourth Thursday of October 2013\n\"9ff1f7b6-1b72-427d-9ee9-82b5bb08b835\" = true\n\n# fourth Friday of November 2013\n\"83bae8ba-1c49-49bc-b632-b7c7e1d7e35f\" = true\n\n# fourth Friday of December 2013\n\"de752d2a-a95e-48d2-835b-93363dac3710\" = true\n\n# fourth Saturday of January 2013\n\"eedd90ad-d581-45db-8312-4c6dcf9cf560\" = true\n\n# fourth Saturday of February 2013\n\"669fedcd-912e-48c7-a0a1-228b34af91d0\" = true\n\n# fourth Sunday of March 2013\n\"648e3849-ea49-44a5-a8a3-9f2a43b3bf1b\" = true\n\n# fourth Sunday of April 2013\n\"f81321b3-99ab-4db6-9267-69c5da5a7823\" = true\n\n# last Monday of March 2013\n\"1af5e51f-5488-4548-aee8-11d7d4a730dc\" = true\n\n# last Monday of April 2013\n\"f29999f2-235e-4ec7-9dab-26f137146526\" = true\n\n# last Tuesday of May 2013\n\"31b097a0-508e-48ac-bf8a-f63cdcf6dc41\" = true\n\n# last Tuesday of June 2013\n\"8c022150-0bb5-4a1f-80f9-88b2e2abcba4\" = true\n\n# last Wednesday of July 2013\n\"0e762194-672a-4bdf-8a37-1e59fdacef12\" = true\n\n# last Wednesday of August 2013\n\"5016386a-f24e-4bd7-b439-95358f491b66\" = true\n\n# last Thursday of September 2013\n\"12ead1a5-cdf9-4192-9a56-2229e93dd149\" = true\n\n# last Thursday of October 2013\n\"7db89e11-7fbe-4e57-ae3c-0f327fbd7cc7\" = true\n\n# last Friday of November 2013\n\"e47a739e-b979-460d-9c8a-75c35ca2290b\" = true\n\n# last Friday of December 2013\n\"5bed5aa9-a57a-4e5d-8997-2cc796a5b0ec\" = true\n\n# last Saturday of January 2013\n\"61e54cba-76f3-4772-a2b1-bf443fda2137\" = true\n\n# last Saturday of February 2013\n\"8b6a737b-2fa9-444c-b1a2-80ce7a2ec72f\" = true\n\n# last Sunday of March 2013\n\"0b63e682-f429-4d19-9809-4a45bd0242dc\" = true\n\n# last Sunday of April 2013\n\"5232307e-d3e3-4afc-8ba6-4084ad987c00\" = true\n\n# last Wednesday of February 2012\n\"0bbd48e8-9773-4e81-8e71-b9a51711e3c5\" = true\n\n# last Wednesday of December 2014\n\"fe0936de-7eee-4a48-88dd-66c07ab1fefc\" = true\n\n# last Sunday of February 2015\n\"2ccf2488-aafc-4671-a24e-2b6effe1b0e2\" = true\n\n# first Friday of December 2012\n\"00c3ce9f-cf36-4b70-90d8-92b32be6830e\" = true\n"
  },
  {
    "path": "exercises/practice/meetup/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/meetup/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/meetup/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/meetup/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/meetup/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/meetup/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/meetup/src/main/kotlin/Meetup.kt",
    "content": "import java.time.DayOfWeek\nimport java.time.LocalDate\n\nclass Meetup {\n\n    // TODO: implement proper constructor\n\n    fun day(dayOfWeek: DayOfWeek, schedule: MeetupSchedule): LocalDate{\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/meetup/src/main/kotlin/MeetupSchedule.kt",
    "content": "enum class MeetupSchedule {\n\n    FIRST, SECOND, THIRD, FOURTH, LAST, TEENTH\n\n}\n"
  },
  {
    "path": "exercises/practice/meetup/src/test/kotlin/MeetupTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport java.time.DayOfWeek\nimport java.time.LocalDate\nimport kotlin.test.assertEquals\n\nclass MeetupTest {\n\n    @Test\n    fun testMonteenthOfMay2013() {\n        val expected = LocalDate.of(2013, 5, 13)\n        val meetup = Meetup(5, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.MONDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testMonteenthOfAugust2013() {\n        val expected = LocalDate.of(2013, 8, 19)\n        val meetup = Meetup(8, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.MONDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testMonteenthOfSeptember2013() {\n        val expected = LocalDate.of(2013, 9, 16)\n        val meetup = Meetup(9, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.MONDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testTuesteenthOfMarch2013() {\n        val expected = LocalDate.of(2013, 3, 19)\n        val meetup = Meetup(3, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.TUESDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testTuesteenthOfApril2013() {\n        val expected = LocalDate.of(2013, 4, 16)\n        val meetup = Meetup(4, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.TUESDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testTuesteenthOfAugust2013() {\n        val expected = LocalDate.of(2013, 8, 13)\n        val meetup = Meetup(8, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.TUESDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testWednesteenthOfJanuary2013() {\n        val expected = LocalDate.of(2013, 1, 16)\n        val meetup = Meetup(1, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.WEDNESDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testWednesteenthOfFebruary2013() {\n        val expected = LocalDate.of(2013, 2, 13)\n        val meetup = Meetup(2, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.WEDNESDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testWednesteenthOfJune2013() {\n        val expected = LocalDate.of(2013, 6, 19)\n        val meetup = Meetup(6, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.WEDNESDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testThursteenthOfMay2013() {\n        val expected = LocalDate.of(2013, 5, 16)\n        val meetup = Meetup(5, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.THURSDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testThursteenthOfJune2013() {\n        val expected = LocalDate.of(2013, 6, 13)\n        val meetup = Meetup(6, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.THURSDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testThursteenthOfSeptember2013() {\n        val expected = LocalDate.of(2013, 9, 19)\n        val meetup = Meetup(9, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.THURSDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFriteenthOfApril2013() {\n        val expected = LocalDate.of(2013, 4, 19)\n        val meetup = Meetup(4, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.FRIDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFriteenthOfAugust2013() {\n        val expected = LocalDate.of(2013, 8, 16)\n        val meetup = Meetup(8, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.FRIDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFriteenthOfSeptember2013() {\n        val expected = LocalDate.of(2013, 9, 13)\n        val meetup = Meetup(9, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.FRIDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testSaturteenthOfFebruary2013() {\n        val expected = LocalDate.of(2013, 2, 16)\n        val meetup = Meetup(2, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SATURDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testSaturteenthOfApril2013() {\n        val expected = LocalDate.of(2013, 4, 13)\n        val meetup = Meetup(4, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SATURDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testSaturteenthOfOctober2013() {\n        val expected = LocalDate.of(2013, 10, 19)\n        val meetup = Meetup(10, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SATURDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testSunteenthOfMay2013() {\n        val expected = LocalDate.of(2013, 5, 19)\n        val meetup = Meetup(5, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SUNDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testSunteenthOfJune2013() {\n        val expected = LocalDate.of(2013, 6, 16)\n        val meetup = Meetup(6, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SUNDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testSunteenthOfOctober2013() {\n        val expected = LocalDate.of(2013, 10, 13)\n        val meetup = Meetup(10, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SUNDAY, MeetupSchedule.TEENTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstMondayOfMarch2013() {\n        val expected = LocalDate.of(2013, 3, 4)\n        val meetup = Meetup(3, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.MONDAY, MeetupSchedule.FIRST))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstMondayOfApril2013() {\n        val expected = LocalDate.of(2013, 4, 1)\n        val meetup = Meetup(4, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.MONDAY, MeetupSchedule.FIRST))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstTuesdayOfMay2013() {\n        val expected = LocalDate.of(2013, 5, 7)\n        val meetup = Meetup(5, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.TUESDAY, MeetupSchedule.FIRST))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstTuesdayOfJune2013() {\n        val expected = LocalDate.of(2013, 6, 4)\n        val meetup = Meetup(6, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.TUESDAY, MeetupSchedule.FIRST))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstWednesdayOfJuly2013() {\n        val expected = LocalDate.of(2013, 7, 3)\n        val meetup = Meetup(7, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.WEDNESDAY, MeetupSchedule.FIRST))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstWednesdayOfAugust2013() {\n        val expected = LocalDate.of(2013, 8, 7)\n        val meetup = Meetup(8, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.WEDNESDAY, MeetupSchedule.FIRST))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstThursdayOfSeptember2013() {\n        val expected = LocalDate.of(2013, 9, 5)\n        val meetup = Meetup(9, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.THURSDAY, MeetupSchedule.FIRST))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstThursdayOfOctober2013() {\n        val expected = LocalDate.of(2013, 10, 3)\n        val meetup = Meetup(10, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.THURSDAY, MeetupSchedule.FIRST))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstFridayOfNovember2013() {\n        val expected = LocalDate.of(2013, 11, 1)\n        val meetup = Meetup(11, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.FRIDAY, MeetupSchedule.FIRST))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstFridayOfDecember2013() {\n        val expected = LocalDate.of(2013, 12, 6)\n        val meetup = Meetup(12, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.FRIDAY, MeetupSchedule.FIRST))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstSaturdayOfJanuary2013() {\n        val expected = LocalDate.of(2013, 1, 5)\n        val meetup = Meetup(1, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SATURDAY, MeetupSchedule.FIRST))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstSaturdayOfFebruary2013() {\n        val expected = LocalDate.of(2013, 2, 2)\n        val meetup = Meetup(2, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SATURDAY, MeetupSchedule.FIRST))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstSundayOfMarch2013() {\n        val expected = LocalDate.of(2013, 3, 3)\n        val meetup = Meetup(3, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SUNDAY, MeetupSchedule.FIRST))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstSundayOfApril2013() {\n        val expected = LocalDate.of(2013, 4, 7)\n        val meetup = Meetup(4, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SUNDAY, MeetupSchedule.FIRST))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondMondayOfMarch2013() {\n        val expected = LocalDate.of(2013, 3, 11)\n        val meetup = Meetup(3, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.MONDAY, MeetupSchedule.SECOND))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondMondayOfApril2013() {\n        val expected = LocalDate.of(2013, 4, 8)\n        val meetup = Meetup(4, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.MONDAY, MeetupSchedule.SECOND))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondTuesdayOfMay2013() {\n        val expected = LocalDate.of(2013, 5, 14)\n        val meetup = Meetup(5, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.TUESDAY, MeetupSchedule.SECOND))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondTuesdayOfJune2013() {\n        val expected = LocalDate.of(2013, 6, 11)\n        val meetup = Meetup(6, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.TUESDAY, MeetupSchedule.SECOND))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondWednesdayOfJuly2013() {\n        val expected = LocalDate.of(2013, 7, 10)\n        val meetup = Meetup(7, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.WEDNESDAY, MeetupSchedule.SECOND))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondWednesdayOfAugust2013() {\n        val expected = LocalDate.of(2013, 8, 14)\n        val meetup = Meetup(8, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.WEDNESDAY, MeetupSchedule.SECOND))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondThursdayOfSeptember2013() {\n        val expected = LocalDate.of(2013, 9, 12)\n        val meetup = Meetup(9, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.THURSDAY, MeetupSchedule.SECOND))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondThursdayOfOctober2013() {\n        val expected = LocalDate.of(2013, 10, 10)\n        val meetup = Meetup(10, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.THURSDAY, MeetupSchedule.SECOND))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondFridayOfNovember2013() {\n        val expected = LocalDate.of(2013, 11, 8)\n        val meetup = Meetup(11, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.FRIDAY, MeetupSchedule.SECOND))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondFridayOfDecember2013() {\n        val expected = LocalDate.of(2013, 12, 13)\n        val meetup = Meetup(12, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.FRIDAY, MeetupSchedule.SECOND))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondSaturdayOfJanuary2013() {\n        val expected = LocalDate.of(2013, 1, 12)\n        val meetup = Meetup(1, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SATURDAY, MeetupSchedule.SECOND))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondSaturdayOfFebruary2013() {\n        val expected = LocalDate.of(2013, 2, 9)\n        val meetup = Meetup(2, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SATURDAY, MeetupSchedule.SECOND))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondSundayOfMarch2013() {\n        val expected = LocalDate.of(2013, 3, 10)\n        val meetup = Meetup(3, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SUNDAY, MeetupSchedule.SECOND))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondSundayOfApril2013() {\n        val expected = LocalDate.of(2013, 4, 14)\n        val meetup = Meetup(4, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SUNDAY, MeetupSchedule.SECOND))\n    }\n\n    @Ignore\n    @Test\n    fun testThirdMondayOfMarch2013() {\n        val expected = LocalDate.of(2013, 3, 18)\n        val meetup = Meetup(3, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.MONDAY, MeetupSchedule.THIRD))\n    }\n\n    @Ignore\n    @Test\n    fun testThirdMondayOfApril2013() {\n        val expected = LocalDate.of(2013, 4, 15)\n        val meetup = Meetup(4, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.MONDAY, MeetupSchedule.THIRD))\n    }\n\n    @Ignore\n    @Test\n    fun testThirdTuesdayOfMay2013() {\n        val expected = LocalDate.of(2013, 5, 21)\n        val meetup = Meetup(5, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.TUESDAY, MeetupSchedule.THIRD))\n    }\n\n    @Ignore\n    @Test\n    fun testThirdTuesdayOfJune2013() {\n        val expected = LocalDate.of(2013, 6, 18)\n        val meetup = Meetup(6, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.TUESDAY, MeetupSchedule.THIRD))\n    }\n\n    @Ignore\n    @Test\n    fun testThirdWednesdayOfJuly2013() {\n        val expected = LocalDate.of(2013, 7, 17)\n        val meetup = Meetup(7, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.WEDNESDAY, MeetupSchedule.THIRD))\n    }\n\n    @Ignore\n    @Test\n    fun testThirdWednesdayOfAugust2013() {\n        val expected = LocalDate.of(2013, 8, 21)\n        val meetup = Meetup(8, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.WEDNESDAY, MeetupSchedule.THIRD))\n    }\n\n    @Ignore\n    @Test\n    fun testThirdThursdayOfSeptember2013() {\n        val expected = LocalDate.of(2013, 9, 19)\n        val meetup = Meetup(9, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.THURSDAY, MeetupSchedule.THIRD))\n    }\n\n    @Ignore\n    @Test\n    fun testThirdThursdayOfOctober2013() {\n        val expected = LocalDate.of(2013, 10, 17)\n        val meetup = Meetup(10, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.THURSDAY, MeetupSchedule.THIRD))\n    }\n\n    @Ignore\n    @Test\n    fun testThirdFridayOfNovember2013() {\n        val expected = LocalDate.of(2013, 11, 15)\n        val meetup = Meetup(11, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.FRIDAY, MeetupSchedule.THIRD))\n    }\n\n    @Ignore\n    @Test\n    fun testThirdFridayOfDecember2013() {\n        val expected = LocalDate.of(2013, 12, 20)\n        val meetup = Meetup(12, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.FRIDAY, MeetupSchedule.THIRD))\n    }\n\n    @Ignore\n    @Test\n    fun testThirdSaturdayOfJanuary2013() {\n        val expected = LocalDate.of(2013, 1, 19)\n        val meetup = Meetup(1, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SATURDAY, MeetupSchedule.THIRD))\n    }\n\n    @Ignore\n    @Test\n    fun testThirdSaturdayOfFebruary2013() {\n        val expected = LocalDate.of(2013, 2, 16)\n        val meetup = Meetup(2, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SATURDAY, MeetupSchedule.THIRD))\n    }\n\n    @Ignore\n    @Test\n    fun testThirdSundayOfMarch2013() {\n        val expected = LocalDate.of(2013, 3, 17)\n        val meetup = Meetup(3, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SUNDAY, MeetupSchedule.THIRD))\n    }\n\n    @Ignore\n    @Test\n    fun testThirdSundayOfApril2013() {\n        val expected = LocalDate.of(2013, 4, 21)\n        val meetup = Meetup(4, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SUNDAY, MeetupSchedule.THIRD))\n    }\n\n    @Ignore\n    @Test\n    fun testFourthMondayOfMarch2013() {\n        val expected = LocalDate.of(2013, 3, 25)\n        val meetup = Meetup(3, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.MONDAY, MeetupSchedule.FOURTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFourthMondayOfApril2013() {\n        val expected = LocalDate.of(2013, 4, 22)\n        val meetup = Meetup(4, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.MONDAY, MeetupSchedule.FOURTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFourthTuesdayOfMay2013() {\n        val expected = LocalDate.of(2013, 5, 28)\n        val meetup = Meetup(5, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.TUESDAY, MeetupSchedule.FOURTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFourthTuesdayOfJune2013() {\n        val expected = LocalDate.of(2013, 6, 25)\n        val meetup = Meetup(6, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.TUESDAY, MeetupSchedule.FOURTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFourthWednesdayOfJuly2013() {\n        val expected = LocalDate.of(2013, 7, 24)\n        val meetup = Meetup(7, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.WEDNESDAY, MeetupSchedule.FOURTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFourthWednesdayOfAugust2013() {\n        val expected = LocalDate.of(2013, 8, 28)\n        val meetup = Meetup(8, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.WEDNESDAY, MeetupSchedule.FOURTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFourthThursdayOfSeptember2013() {\n        val expected = LocalDate.of(2013, 9, 26)\n        val meetup = Meetup(9, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.THURSDAY, MeetupSchedule.FOURTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFourthThursdayOfOctober2013() {\n        val expected = LocalDate.of(2013, 10, 24)\n        val meetup = Meetup(10, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.THURSDAY, MeetupSchedule.FOURTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFourthFridayOfNovember2013() {\n        val expected = LocalDate.of(2013, 11, 22)\n        val meetup = Meetup(11, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.FRIDAY, MeetupSchedule.FOURTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFourthFridayOfDecember2013() {\n        val expected = LocalDate.of(2013, 12, 27)\n        val meetup = Meetup(12, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.FRIDAY, MeetupSchedule.FOURTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFourthSaturdayOfJanuary2013() {\n        val expected = LocalDate.of(2013, 1, 26)\n        val meetup = Meetup(1, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SATURDAY, MeetupSchedule.FOURTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFourthSaturdayOfFebruary2013() {\n        val expected = LocalDate.of(2013, 2, 23)\n        val meetup = Meetup(2, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SATURDAY, MeetupSchedule.FOURTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFourthSundayOfMarch2013() {\n        val expected = LocalDate.of(2013, 3, 24)\n        val meetup = Meetup(3, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SUNDAY, MeetupSchedule.FOURTH))\n    }\n\n    @Ignore\n    @Test\n    fun testFourthSundayOfApril2013() {\n        val expected = LocalDate.of(2013, 4, 28)\n        val meetup = Meetup(4, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SUNDAY, MeetupSchedule.FOURTH))\n    }\n\n    @Ignore\n    @Test\n    fun testLastMondayOfMarch2013() {\n        val expected = LocalDate.of(2013, 3, 25)\n        val meetup = Meetup(3, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.MONDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastMondayOfApril2013() {\n        val expected = LocalDate.of(2013, 4, 29)\n        val meetup = Meetup(4, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.MONDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastTuesdayOfMay2013() {\n        val expected = LocalDate.of(2013, 5, 28)\n        val meetup = Meetup(5, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.TUESDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastTuesdayOfJune2013() {\n        val expected = LocalDate.of(2013, 6, 25)\n        val meetup = Meetup(6, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.TUESDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastWednesdayOfJuly2013() {\n        val expected = LocalDate.of(2013, 7, 31)\n        val meetup = Meetup(7, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.WEDNESDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastWednesdayOfAugust2013() {\n        val expected = LocalDate.of(2013, 8, 28)\n        val meetup = Meetup(8, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.WEDNESDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastThursdayOfSeptember2013() {\n        val expected = LocalDate.of(2013, 9, 26)\n        val meetup = Meetup(9, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.THURSDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastThursdayOfOctober2013() {\n        val expected = LocalDate.of(2013, 10, 31)\n        val meetup = Meetup(10, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.THURSDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastFridayOfNovember2013() {\n        val expected = LocalDate.of(2013, 11, 29)\n        val meetup = Meetup(11, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.FRIDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastFridayOfDecember2013() {\n        val expected = LocalDate.of(2013, 12, 27)\n        val meetup = Meetup(12, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.FRIDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastSaturdayOfJanuary2013() {\n        val expected = LocalDate.of(2013, 1, 26)\n        val meetup = Meetup(1, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SATURDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastSaturdayOfFebruary2013() {\n        val expected = LocalDate.of(2013, 2, 23)\n        val meetup = Meetup(2, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SATURDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastSundayOfMarch2013() {\n        val expected = LocalDate.of(2013, 3, 31)\n        val meetup = Meetup(3, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SUNDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastSundayOfApril2013() {\n        val expected = LocalDate.of(2013, 4, 28)\n        val meetup = Meetup(4, 2013)\n        assertEquals(expected, meetup.day(DayOfWeek.SUNDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastWednesdayOfFebruary2012() {\n        val expected = LocalDate.of(2012, 2, 29)\n        val meetup = Meetup(2, 2012)\n        assertEquals(expected, meetup.day(DayOfWeek.WEDNESDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastWednesdayOfDecember2014() {\n        val expected = LocalDate.of(2014, 12, 31)\n        val meetup = Meetup(12, 2014)\n        assertEquals(expected, meetup.day(DayOfWeek.WEDNESDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testLastSundayOfFebruary2015() {\n        val expected = LocalDate.of(2015, 2, 22)\n        val meetup = Meetup(2, 2015)\n        assertEquals(expected, meetup.day(DayOfWeek.SUNDAY, MeetupSchedule.LAST))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstFridayOfDecember2012() {\n        val expected = LocalDate.of(2012, 12, 7)\n        val meetup = Meetup(12, 2012)\n        assertEquals(expected, meetup.day(DayOfWeek.FRIDAY, MeetupSchedule.FIRST))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/minesweeper/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to add the mine counts to empty squares in a completed Minesweeper board.\nThe board itself is a rectangle composed of squares that are either empty (`' '`) or a mine (`'*'`).\n\nFor each empty square, count the number of mines adjacent to it (horizontally, vertically, diagonally).\nIf the empty square has no adjacent mines, leave it empty.\nOtherwise replace it with the adjacent mines count.\n\nFor example, you may receive a 5 x 4 board like this (empty spaces are represented here with the '·' character for display on screen):\n\n```text\n·*·*·\n··*··\n··*··\n·····\n```\n\nWhich your code should transform into this:\n\n```text\n1*3*1\n13*31\n·2*2·\n·111·\n```\n"
  },
  {
    "path": "exercises/practice/minesweeper/.docs/introduction.md",
    "content": "# Introduction\n\n[Minesweeper][wikipedia] is a popular game where the user has to find the mines using numeric hints that indicate how many mines are directly adjacent (horizontally, vertically, diagonally) to a square.\n\n[wikipedia]: https://en.wikipedia.org/wiki/Minesweeper_(video_game)\n"
  },
  {
    "path": "exercises/practice/minesweeper/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Minesweeper.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/MinesweeperBoardTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Minesweeper.kt\"\n    ]\n  },\n  \"blurb\": \"Add the numbers to a minesweeper board.\"\n}\n"
  },
  {
    "path": "exercises/practice/minesweeper/.meta/src/reference/kotlin/Minesweeper.kt",
    "content": "import kotlin.math.max\nimport kotlin.math.min\n\nprivate const val MINE_CHAR = '*'\nprivate const val SPACE_CHAR = ' '\n\ndata class MinesweeperBoard(val mineLocations: List<String>) {\n\n    private val numberOfRows by lazy {\n        mineLocations.size\n    }\n\n    private val numberOfColumns by lazy {\n        if (mineLocations.isEmpty()) 0 else mineLocations[0].length\n    }\n\n    fun withNumbers() = (0 until numberOfRows).map { getRowWithNumbers(it) }\n\n    private fun getRowWithNumbers(rowNumber: Int) =\n            (0 until numberOfColumns)\n                    .map { columnNumber -> getCellNumber(rowNumber, columnNumber) }\n                    .joinToString(\"\")\n\n    private fun getCellNumber(rowNumber: Int, columnNumber: Int): Char {\n        // If (rowNumber, columnNumber) is a mine, we're done.\n        if (mineLocations[rowNumber][columnNumber] == MINE_CHAR) {\n            return MINE_CHAR\n        }\n\n        val mineCount = computeMineCountAround(rowNumber, columnNumber)\n\n        // If computed count is positive, add it to the annotated row. Otherwise, add a blank space.\n        return if (mineCount > 0) Character.forDigit(mineCount, 10) else SPACE_CHAR\n    }\n\n    private fun computeMineCountAround(rowNumber: Int, columnNumber: Int): Int {\n        var result = 0\n\n        // Compute row and column ranges to inspect (respecting board edges).\n        val minRowToInspect = max(rowNumber - 1, 0)\n        val maxRowToInspect = min(rowNumber + 1, numberOfRows - 1)\n        val minColToInspect = max(columnNumber - 1, 0)\n        val maxColToInspect = min(columnNumber + 1, numberOfColumns - 1)\n\n        // Count mines in the cells surrounding (row, col).\n        for (rowToInspect in minRowToInspect..maxRowToInspect) {\n            for (colToInspect in minColToInspect..maxColToInspect) {\n                if (mineLocations[rowToInspect][colToInspect] == MINE_CHAR) {\n                    result += 1\n                }\n            }\n        }\n\n        return result\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/minesweeper/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# no rows\n\"0c5ec4bd-dea7-4138-8651-1203e1cb9f44\" = true\n\n# no columns\n\"650ac4c0-ad6b-4b41-acde-e4ea5852c3b8\" = true\n\n# no mines\n\"6fbf8f6d-a03b-42c9-9a58-b489e9235478\" = true\n\n# minefield with only mines\n\"61aff1c4-fb31-4078-acad-cd5f1e635655\" = true\n\n# mine surrounded by spaces\n\"84167147-c504-4896-85d7-246b01dea7c5\" = true\n\n# space surrounded by mines\n\"cb878f35-43e3-4c9d-93d9-139012cccc4a\" = true\n\n# horizontal line\n\"7037f483-ddb4-4b35-b005-0d0f4ef4606f\" = true\n\n# horizontal line, mines at edges\n\"e359820f-bb8b-4eda-8762-47b64dba30a6\" = true\n\n# vertical line\n\"c5198b50-804f-47e9-ae02-c3b42f7ce3ab\" = true\n\n# vertical line, mines at edges\n\"0c79a64d-703d-4660-9e90-5adfa5408939\" = true\n\n# cross\n\"4b098563-b7f3-401c-97c6-79dd1b708f34\" = true\n\n# large minefield\n\"04a260f1-b40a-4e89-839e-8dd8525abe0e\" = true\n"
  },
  {
    "path": "exercises/practice/minesweeper/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/minesweeper/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/minesweeper/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/minesweeper/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/minesweeper/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/minesweeper/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/minesweeper/src/main/kotlin/Minesweeper.kt",
    "content": "data class MinesweeperBoard(val todo: Nothing) {\n\n    // TODO: Implement proper constructor\n\n    fun withNumbers(): List<String> {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/minesweeper/src/test/kotlin/MinesweeperBoardTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.rules.ExpectedException\nimport kotlin.test.assertEquals\n\nclass MinesweeperBoardTest {\n\n    /*\n     * See https://github.com/junit-team/junit4/wiki/Rules for information on JUnit Rules in general and\n     * ExpectedExceptions in particular.\n     */\n    @Rule\n    @JvmField\n    var expectedException: ExpectedException = ExpectedException.none()\n\n    @Test\n    fun testInputBoardWithNoRowsAndNoColumns() {\n        val inputBoard = emptyList<String>()\n        val expectedNumberedBoard = emptyList<String>()\n        val actualNumberedBoard = MinesweeperBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithOneRowAndNoColumns() {\n        val inputBoard = listOf(\"\")\n        val expectedNumberedBoard = listOf(\"\")\n        val actualNumberedBoard = MinesweeperBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithNoMines() {\n        val inputBoard = listOf(\n                \"   \",\n                \"   \",\n                \"   \"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \"   \",\n                \"   \",\n                \"   \"\n        )\n\n        val actualNumberedBoard = MinesweeperBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithOnlyMines() {\n        val inputBoard = listOf(\n                \"***\",\n                \"***\",\n                \"***\"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \"***\",\n                \"***\",\n                \"***\"\n        )\n\n        val actualNumberedBoard = MinesweeperBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithSingleMineAtCenter() {\n        val inputBoard = listOf(\n                \"   \",\n                \" * \",\n                \"   \"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \"111\",\n                \"1*1\",\n                \"111\"\n        )\n\n        val actualNumberedBoard = MinesweeperBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithMinesAroundPerimeter() {\n        val inputBoard = listOf(\n                \"***\",\n                \"* *\",\n                \"***\"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \"***\",\n                \"*8*\",\n                \"***\"\n        )\n\n        val actualNumberedBoard = MinesweeperBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithSingleRowAndTwoMines() {\n        val inputBoard = listOf(\" * * \")\n\n        val expectedNumberedBoard = listOf(\"1*2*1\")\n\n        val actualNumberedBoard = MinesweeperBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithSingleRowAndTwoMinesAtEdges() {\n        val inputBoard = listOf(\"*   *\")\n\n        val expectedNumberedBoard = listOf(\"*1 1*\")\n\n        val actualNumberedBoard = MinesweeperBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithSingleColumnAndTwoMines() {\n        val inputBoard = listOf(\n                \" \",\n                \"*\",\n                \" \",\n                \"*\",\n                \" \"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \"1\",\n                \"*\",\n                \"2\",\n                \"*\",\n                \"1\"\n        )\n\n        val actualNumberedBoard = MinesweeperBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithSingleColumnAndTwoMinesAtEdges() {\n        val inputBoard = listOf(\n                \"*\",\n                \" \",\n                \" \",\n                \" \",\n                \"*\"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \"*\",\n                \"1\",\n                \" \",\n                \"1\",\n                \"*\"\n        )\n\n        val actualNumberedBoard = MinesweeperBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testInputBoardWithMinesInCross() {\n        val inputBoard = listOf(\n                \"  *  \",\n                \"  *  \",\n                \"*****\",\n                \"  *  \",\n                \"  *  \"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \" 2*2 \",\n                \"25*52\",\n                \"*****\",\n                \"25*52\",\n                \" 2*2 \"\n        )\n\n        val actualNumberedBoard = MinesweeperBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n    @Ignore\n    @Test\n    fun testLargeInputBoard() {\n        val inputBoard = listOf(\n                \" *  * \",\n                \"  *   \",\n                \"    * \",\n                \"   * *\",\n                \" *  * \",\n                \"      \"\n        )\n\n        val expectedNumberedBoard = listOf(\n                \"1*22*1\",\n                \"12*322\",\n                \" 123*2\",\n                \"112*4*\",\n                \"1*22*2\",\n                \"111111\"\n        )\n\n        val actualNumberedBoard = MinesweeperBoard(inputBoard).withNumbers()\n\n        assertEquals(expectedNumberedBoard, actualNumberedBoard)\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/nth-prime/.docs/instructions.md",
    "content": "# Instructions\n\nGiven a number n, determine what the nth prime is.\n\nBy listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.\n\nIf your language provides methods in the standard library to deal with prime numbers, pretend they don't exist and implement them yourself.\n"
  },
  {
    "path": "exercises/practice/nth-prime/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"kytrinyx\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/NthPrime.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/PrimeTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/NthPrime.kt\"\n    ]\n  },\n  \"blurb\": \"Given a number n, determine what the nth prime is.\",\n  \"source\": \"A variation on Problem 7 at Project Euler\",\n  \"source_url\": \"https://projecteuler.net/problem=7\"\n}\n"
  },
  {
    "path": "exercises/practice/nth-prime/.meta/src/reference/kotlin/NthPrime.kt",
    "content": "import java.math.BigInteger\n\nobject Prime {\n\n    fun nth(n: Int): Int {\n        require(n > 0) { \"There is no zeroth prime.\" }\n\n        return primes().drop(n - 1).first().toInt()\n    }\n\n    private fun primes(): Sequence<BigInteger> = generateSequence(BigInteger.valueOf(2)) { previous ->\n        previous.nextProbablePrime()\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/nth-prime/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# first prime\n\"75c65189-8aef-471a-81de-0a90c728160c\" = true\n\n# second prime\n\"2c38804c-295f-4701-b728-56dea34fd1a0\" = true\n\n# sixth prime\n\"56692534-781e-4e8c-b1f9-3e82c1640259\" = true\n\n# big prime\n\"fce1e979-0edb-412d-93aa-2c744e8f50ff\" = true\n\n# there is no zeroth prime\n\"bd0a9eae-6df7-485b-a144-80e13c7d55b2\" = true\n"
  },
  {
    "path": "exercises/practice/nth-prime/.meta/version",
    "content": "2.1.0\n"
  },
  {
    "path": "exercises/practice/nth-prime/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/nth-prime/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/nth-prime/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/nth-prime/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/nth-prime/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/nth-prime/src/main/kotlin/NthPrime.kt",
    "content": "object Prime {\n\n    fun nth(n: Int): Int {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/nth-prime/src/test/kotlin/PrimeTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport org.junit.Rule\nimport org.junit.rules.ExpectedException\nimport kotlin.test.assertEquals\n\nclass PrimeTest {\n\n    @Rule\n    @JvmField\n    var expectedException: ExpectedException = ExpectedException.none()\n\n    @Test\n    fun firstPrime() {\n        assertEquals(2, Prime.nth(1))\n    }\n\n    @Ignore\n    @Test\n    fun secondPrime() {\n        assertEquals(3, Prime.nth(2))\n    }\n\n    @Ignore\n    @Test\n    fun sixthPrime() {\n        assertEquals(13, Prime.nth(6))\n    }\n\n    @Ignore\n    @Test\n    fun bigPrime() {\n        assertEquals(104743, Prime.nth(10001))\n    }\n\n    @Ignore\n    @Test\n    fun undefinedPrime() {\n        expectedException.expect(IllegalArgumentException::class.java)\n        expectedException.expectMessage(\"There is no zeroth prime.\")\n\n        Prime.nth(0)\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/.approaches/config.json",
    "content": "{\n  \"introduction\": {\n    \"authors\": [\n      \"ErwinOlie\"\n    ]\n  },\n  \"approaches\": [\n    {\n      \"uuid\": \"56375e89-328b-4fb6-9195-91fd8e623fd3\",\n      \"slug\": \"groupby-plus\",\n      \"title\": \"groupBy with +\",\n      \"blurb\": \"Use groupBy to count the nucleotides and add them to the base case.\",\n      \"authors\": [\n        \"ErwinOlie\"\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/.approaches/groupby-plus/content.md",
    "content": "# `groupBy` with `+`\n\n```kotlin\nclass Dna(val sequence: String) {\n    init {\n        require(sequence.all { it in \"ACGT\" })\n    }\n    val nucleotideCounts\n        get() = mapOf('A' to 0, 'C' to 0, 'G' to 0, 'T' to 0) + sequence.groupingBy { it }.eachCount()\n}\n```\n\n## Verification\nWe receive a sequence as input, which we have to verify.\nBecause the sequence is part of the primary constructor, which can't contain runnable code, we have to place the check in an [_initializer block_][stdlib-constructors].\nIn Kotlin it's idiomatic to use the [`require`][stdlib-require] keyword for verification.\n`require` will throw an `IllegalArgumentException` if the given value is `false`.\n```kotlin\ninit {\n    require(sequence.all { it in \"ACGT\" })\n}\n```\n\n## Base Map\nWe define a base map with a zero value for every nucleotide.\nWe do this to ensure that every nucleotide will be present in the output, even if there is no count.\nAfterward we can overwrite some of the values by using the `+` operator.\nNote that the [`+` operator on maps][map-plus] does not add the values but overwrites them.\n```kotlin\nval nucleotideCounts\n    get() = mapOf('A' to 0, 'C' to 0, 'G' to 0, 'T' to 0)\n```\n\n## Counting Nucleotides\nWe use the `.groupingBy` function to create a [`Grouping`][stdlib-grouping] of the nucleotides.\nBy using the `.eachCount()` function we turn the [`Grouping`][stdlib-grouping] in a Map.\nFor example: `\"ACA\".groupingBy { it }.eachCount()` results in `{A=2, C=1}`.\nAfter [adding][map-plus] the maps together we receive our final answer.\n```kotlin\nval nucleotideCounts\n    get() = mapOf('A' to 0, 'C' to 0, 'G' to 0, 'T' to 0) + sequence.groupingBy { it }.eachCount()\n```\n\n[stdlib-require]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/require.html\n[stdlib-constructors]: https://kotlinlang.org/docs/classes.html#constructors\n[stdlib-grouping]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-grouping/\n[stdlib-eachcount]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/each-count.html\n[map-plus]: https://kotlinlang.org/docs/map-operations.html#plus-and-minus-operators\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/.approaches/groupby-plus/snippet.txt",
    "content": "class Dna(val sequence: String) {\n    init {\n        require(sequence.all { it in \"ACGT\" })\n    }\n    val nucleotideCounts\n        get() = mapOf('A' to 0, 'C' to 0, 'G' to 0, 'T' to 0) + sequence.groupingBy { it }.eachCount()\n}\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/.approaches/introduction.md",
    "content": "# Introduction\n\nEach solution has to contain the following three elements:\n- Check the input for any invalid characters.\n- Count the presence of every nucleotide.\n- Ensure that the missing nucleotides are also present in the output.\n\n## Approach: `groupBy` with `+`\nOne approach is to use `groupBy` and the `+` operator:\n```kotlin\nclass Dna(val sequence: String) {\n    init {\n        require(sequence.all { it in \"ACGT\" })\n    }\n\n    val nucleotideCounts\n        get() = mapOf('A' to 0, 'C' to 0, 'G' to 0, 'T' to 0) + sequence.groupingBy { it }.eachCount()\n}\n```\n\nFor more information, check the [`groupBy` with `+` approach][approach-groupby-plus].\n\n[approach-groupby-plus]: https://exercism.org/tracks/kotlin/exercises/nucleotide-count/approaches/groupby-plus\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/.docs/instructions.md",
    "content": "# Instructions\n\nEach of us inherits from our biological parents a set of chemical instructions known as DNA that influence how our bodies are constructed.\nAll known life depends on DNA!\n\n> Note: You do not need to understand anything about nucleotides or DNA to complete this exercise.\n\nDNA is a long chain of other chemicals and the most important are the four nucleotides, adenine, cytosine, guanine and thymine.\nA single DNA chain can contain billions of these four nucleotides and the order in which they occur is important!\nWe call the order of these nucleotides in a bit of DNA a \"DNA sequence\".\n\nWe represent a DNA sequence as an ordered collection of these four nucleotides and a common way to do that is with a string of characters such as \"ATTACG\" for a DNA sequence of 6 nucleotides.\n'A' for adenine, 'C' for cytosine, 'G' for guanine, and 'T' for thymine.\n\nGiven a string representing a DNA sequence, count how many of each nucleotide is present.\nIf the string contains characters that aren't A, C, G, or T then it is invalid and you should signal an error.\n\nFor example:\n\n```text\n\"GATTACA\" -> 'A': 3, 'C': 1, 'G': 1, 'T': 2\n\"INVALID\" -> error\n```\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Dna.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/DnaTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Dna.kt\"\n    ]\n  },\n  \"blurb\": \"Given a DNA string, compute how many times each nucleotide occurs in the string.\",\n  \"source\": \"The Calculating DNA Nucleotides_problem at Rosalind\",\n  \"source_url\": \"https://rosalind.info/problems/dna/\"\n}\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/.meta/src/reference/kotlin/Dna.kt",
    "content": "class Dna(strand: String) {\n\n    init {\n        require(strand.matches(Regex(\"^[$nucleotides]*$\"))) { \"DNA sequence contains invalid nucleotides sequence.\" }\n    }\n\n    companion object Dna {\n        const val nucleotides = \"ATCG\"\n        val emptyNucleotideCounts = nucleotides.map { it to 0 }.toMap()\n    }\n\n    val nucleotideCounts: Map<Char, Int> by lazy {\n        emptyNucleotideCounts + strand.groupBy { it }.mapValues { it.value.size }\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# empty strand\n\"3e5c30a8-87e2-4845-a815-a49671ade970\" = true\n\n# can count one nucleotide in single-character input\n\"a0ea42a6-06d9-4ac6-828c-7ccaccf98fec\" = true\n\n# strand with repeated nucleotide\n\"eca0d565-ed8c-43e7-9033-6cefbf5115b5\" = true\n\n# strand with multiple nucleotides\n\"40a45eac-c83f-4740-901a-20b22d15a39f\" = true\n\n# strand with invalid nucleotides\n\"b4c47851-ee9e-4b0a-be70-a86e343bd851\" = true\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/.meta/version",
    "content": "1.3.0\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/src/main/kotlin/Dna.kt",
    "content": "class Dna {\n\n    // TODO: Implement proper constructor\n\n    val nucleotideCounts: Map<Char, Int>\n        get() {\n            TODO(\"Implement this function to complete the task\")\n        }\n}\n"
  },
  {
    "path": "exercises/practice/nucleotide-count/src/test/kotlin/DnaTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass DnaTest {\n\n    @Test\n    fun emptyDnaStringHasNoNucleotides() {\n        val dna = Dna(\"\")\n        val expected = mapOf('A' to 0, 'C' to 0, 'G' to 0, 'T' to 0)\n\n        assertEquals(expected, dna.nucleotideCounts)\n    }\n\n    @Ignore\n    @Test\n    fun canCountOneNucleotideInSingleCharacterInput() {\n        val dna = Dna(\"G\")\n        val expected = mapOf('A' to 0, 'C' to 0, 'G' to 1, 'T' to 0)\n\n        assertEquals(expected, dna.nucleotideCounts)\n    }\n\n    @Ignore\n    @Test\n    fun canCountRepeatedNucleotide() {\n        val dna = Dna(\"GGGGGGG\")\n        val expected = mapOf('A' to 0, 'C' to 0, 'G' to 7, 'T' to 0)\n\n        assertEquals(expected, dna.nucleotideCounts)\n    }\n\n    @Ignore\n    @Test\n    fun canCountMultipleNucleotides() {\n        val dna = Dna(\"AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC\")\n        val expected = mapOf('A' to 20, 'C' to 12, 'G' to 17, 'T' to 21)\n\n        assertEquals(expected, dna.nucleotideCounts)\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun validatesNucleotides() {\n        Dna(\"AGXXACT\")\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/pangram/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to figure out if a sentence is a pangram.\n\nA pangram is a sentence using every letter of the alphabet at least once.\nIt is case insensitive, so it doesn't matter if a letter is lower-case (e.g. `k`) or upper-case (e.g. `K`).\n\nFor this exercise, a sentence is a pangram if it contains each of the 26 letters in the English alphabet.\n"
  },
  {
    "path": "exercises/practice/pangram/.docs/introduction.md",
    "content": "# Introduction\n\nYou work for a company that sells fonts through their website.\nThey'd like to show a different sentence each time someone views a font on their website.\nTo give a comprehensive sense of the font, the random sentences should use **all** the letters in the English alphabet.\n\nThey're running a competition to get suggestions for sentences that they can use.\nYou're in charge of checking the submissions to see if they are valid.\n\n~~~~exercism/note\nPangram comes from Greek, παν γράμμα, pan gramma, which means \"every letter\".\n\nThe best known English pangram is:\n\n> The quick brown fox jumps over the lazy dog.\n~~~~\n"
  },
  {
    "path": "exercises/practice/pangram/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"enixander\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"markhobson\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Pangram.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/PangramTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Pangram.kt\"\n    ]\n  },\n  \"blurb\": \"Determine if a sentence is a pangram.\",\n  \"source\": \"Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Pangram\"\n}\n"
  },
  {
    "path": "exercises/practice/pangram/.meta/src/reference/kotlin/Pangram.kt",
    "content": "object Pangram {\n    const val alphaLength = 26\n    fun isPangram(input: String) = input.lowercase().replace(Regex(\"[^a-z]\"), \"\").toSet().size == alphaLength\n}\n"
  },
  {
    "path": "exercises/practice/pangram/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# empty sentence\n\"64f61791-508e-4f5c-83ab-05de042b0149\" = true\n\n# perfect lower case\n\"74858f80-4a4d-478b-8a5e-c6477e4e4e84\" = true\n\n# only lower case\n\"61288860-35ca-4abe-ba08-f5df76ecbdcd\" = true\n\n# missing the letter 'x'\n\"6564267d-8ac5-4d29-baf2-e7d2e304a743\" = true\n\n# missing the letter 'h'\n\"c79af1be-d715-4cdb-a5f2-b2fa3e7e0de0\" = true\n\n# with underscores\n\"d835ec38-bc8f-48e4-9e36-eb232427b1df\" = true\n\n# with numbers\n\"8cc1e080-a178-4494-b4b3-06982c9be2a8\" = true\n\n# missing letters replaced by numbers\n\"bed96b1c-ff95-45b8-9731-fdbdcb6ede9a\" = true\n\n# mixed case and punctuation\n\"938bd5d8-ade5-40e2-a2d9-55a338a01030\" = true\n\n# case insensitive\n\"2577bf54-83c8-402d-a64b-a2c0f7bb213a\" = true\n"
  },
  {
    "path": "exercises/practice/pangram/.meta/version",
    "content": "2.0.0\n"
  },
  {
    "path": "exercises/practice/pangram/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/pangram/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/pangram/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/pangram/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/pangram/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/pangram/src/main/kotlin/Pangram.kt",
    "content": "object Pangram {\n\n    fun isPangram(input: String): Boolean {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/pangram/src/test/kotlin/PangramTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertFalse\nimport kotlin.test.assertTrue\n\nclass PangramTest {\n\n    @Test\n    fun emptySentence() {\n        assertFalse(Pangram.isPangram(\"\"))\n    }\n\n    @Ignore\n    @Test\n    fun perfectLowerCase() {\n        assertTrue(Pangram.isPangram(\"abcdefghijklmnopqrstuvwxyz\"))\n    }\n\n    @Ignore\n    @Test\n    fun onlyLowerCase() {\n        assertTrue(Pangram.isPangram(\"the quick brown fox jumps over the lazy dog\"))\n    }\n\n    @Ignore\n    @Test\n    fun missingTheLetterX() {\n        assertFalse(Pangram.isPangram(\"a quick movement of the enemy will jeopardize five gunboats\"))\n    }\n\n    @Ignore\n    @Test\n    fun missingTheLetterH() {\n        assertFalse(Pangram.isPangram(\"five boxing wizards jump quickly at it\"))\n    }\n\n    @Ignore\n    @Test\n    fun withUnderscores() {\n        assertTrue(Pangram.isPangram(\"the_quick_brown_fox_jumps_over_the_lazy_dog\"))\n    }\n\n    @Ignore\n    @Test\n    fun withNumbers() {\n        assertTrue(Pangram.isPangram(\"the 1 quick brown fox jumps over the 2 lazy dogs\"))\n    }\n\n    @Ignore\n    @Test\n    fun missingLettersReplacedByNumbers() {\n        assertFalse(Pangram.isPangram(\"7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog\"))\n    }\n\n    @Ignore\n    @Test\n    fun mixedCaseAndPunctuation() {\n        assertTrue(Pangram.isPangram(\"\\\"Five quacking Zephyrs jolt my wax bed.\\\"\"))\n    }\n\n    @Ignore\n    @Test\n    fun caseInsensitive() {\n        assertFalse(Pangram.isPangram(\"the quick brown fox jumps over with lazy FX\"))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/pascals-triangle/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to output the first N rows of Pascal's triangle.\n\n[Pascal's triangle][wikipedia] is a triangular array of positive integers.\n\nIn Pascal's triangle, the number of values in a row is equal to its row number (which starts at one).\nTherefore, the first row has one value, the second row has two values, and so on.\n\nThe first (topmost) row has a single value: `1`.\nSubsequent rows' values are computed by adding the numbers directly to the right and left of the current position in the previous row.\n\nIf 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).\n\n## Example\n\nLet's look at the first 5 rows of Pascal's Triangle:\n\n```text\n    1\n   1 1\n  1 2 1\n 1 3 3 1\n1 4 6 4 1\n```\n\nThe topmost row has one value, which is `1`.\n\nThe leftmost and rightmost values have only one preceding position to consider, which is the position to its right respectively to its left.\nWith the topmost value being `1`, it follows from this that all the leftmost and rightmost values are also `1`.\n\nThe other values all have two positions to consider.\nFor 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`:\n\n[wikipedia]: https://en.wikipedia.org/wiki/Pascal%27s_triangle\n"
  },
  {
    "path": "exercises/practice/pascals-triangle/.docs/introduction.md",
    "content": "# Introduction\n\nWith the weather being great, you're not looking forward to spending an hour in a classroom.\nAnnoyed, you enter the class room, where you notice a strangely satisfying triangle shape on the blackboard.\nWhilst 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.\nWeird!\n\nNot long after you sit down, your teacher enters the room and explains that this triangle is the famous [Pascal's triangle][wikipedia].\n\nOver the next hour, your teacher reveals some amazing things hidden in this triangle:\n\n- It can be used to compute how many ways you can pick K elements from N values.\n- It contains the Fibonacci sequence.\n- If you color odd and even numbers differently, you get a beautiful pattern called the [Sierpiński triangle][wikipedia-sierpinski-triangle].\n\nThe teacher implores you and your classmates to look up other uses, and assures you that there are lots more!\nAt that moment, the school bell rings.\nYou realize that for the past hour, you were completely absorbed in learning about Pascal's triangle.\nYou quickly grab your laptop from your bag and go outside, ready to enjoy both the sunshine _and_ the wonders of Pascal's triangle.\n\n[wikipedia]: https://en.wikipedia.org/wiki/Pascal%27s_triangle\n[wikipedia-sierpinski-triangle]: https://en.wikipedia.org/wiki/Sierpi%C5%84ski_triangle\n"
  },
  {
    "path": "exercises/practice/pascals-triangle/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/PascalsTriangle.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/PascalsTriangleTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/PascalsTriangle.kt\"\n    ]\n  },\n  \"blurb\": \"Compute Pascal's triangle up to a given number of rows.\",\n  \"source\": \"Pascal's Triangle at Wolfram Math World\",\n  \"source_url\": \"https://www.wolframalpha.com/input/?i=Pascal%27s+triangle\"\n}\n"
  },
  {
    "path": "exercises/practice/pascals-triangle/.meta/src/reference/kotlin/PascalsTriangle.kt",
    "content": "object PascalsTriangle {\n\n    fun computeTriangle(rows: Int): List<List<Int>> {\n        require(rows >= 0) { \"Rows can't be negative!\" }\n\n        if (rows == 0) return emptyList()\n        return (1..rows).map { buildTriangleRow(it) }\n    }\n\n    private fun buildTriangleRow(row: Int): List<Int> {\n        var m = 1\n        return listOf(1) + (1 until row).map { col ->\n            m = m * (row - col) / col\n            return@map m\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/pascals-triangle/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# zero rows\n\"9920ce55-9629-46d5-85d6-4201f4a4234d\" = true\n\n# single row\n\"70d643ce-a46d-4e93-af58-12d88dd01f21\" = true\n\n# two rows\n\"a6e5a2a2-fc9a-4b47-9f4f-ed9ad9fbe4bd\" = true\n\n# three rows\n\"97206a99-79ba-4b04-b1c5-3c0fa1e16925\" = true\n\n# four rows\n\"565a0431-c797-417c-a2c8-2935e01ce306\" = true\n\n# five rows\n\"06f9ea50-9f51-4eb2-b9a9-c00975686c27\" = true\n\n# six rows\n\"c3912965-ddb4-46a9-848e-3363e6b00b13\" = true\n\n# ten rows\n\"6cb26c66-7b57-4161-962c-81ec8c99f16b\" = true\n"
  },
  {
    "path": "exercises/practice/pascals-triangle/.meta/version",
    "content": "1.5.0\n"
  },
  {
    "path": "exercises/practice/pascals-triangle/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/pascals-triangle/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/pascals-triangle/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/pascals-triangle/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/pascals-triangle/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/pascals-triangle/src/main/kotlin/PascalsTriangle.kt",
    "content": "object PascalsTriangle {\n\n    fun computeTriangle(rows: Int): List<List<Int>> {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/pascals-triangle/src/test/kotlin/PascalsTriangleTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass PascalsTriangleTest {\n    @Test\n    fun `zero rows`() = assertTriangleEquals(\n            0,\n            emptyList())\n\n\n    @Ignore\n    @Test\n    fun `single row`() = assertTriangleEquals(\n            1,\n            listOf(\n                    listOf(1)))\n\n    @Ignore\n    @Test\n    fun `two rows`() = assertTriangleEquals(\n            2,\n            listOf(\n                    listOf(1),\n                    listOf(1, 1)))\n\n    @Ignore\n    @Test\n    fun `tree rows`() = assertTriangleEquals(\n            3,\n            listOf(\n                    listOf(1),\n                    listOf(1, 1),\n                    listOf(1, 2, 1)))\n\n    @Ignore\n    @Test\n    fun `four rows`() = assertTriangleEquals(\n            4,\n            listOf(\n                    listOf(1),\n                    listOf(1, 1),\n                    listOf(1, 2, 1),\n                    listOf(1, 3, 3, 1)))\n\n    @Ignore\n    @Test\n    fun `five rows`() = assertTriangleEquals(\n            5,\n            listOf(\n                    listOf(1),\n                    listOf(1, 1),\n                    listOf(1, 2, 1),\n                    listOf(1, 3, 3, 1),\n                    listOf(1, 4, 6, 4, 1)))\n\n    @Ignore\n    @Test\n    fun `six rows`() = assertTriangleEquals(\n            6,\n            listOf(\n                    listOf(1),\n                    listOf(1, 1),\n                    listOf(1, 2, 1),\n                    listOf(1, 3, 3, 1),\n                    listOf(1, 4, 6, 4, 1),\n                    listOf(1, 5, 10, 10, 5, 1)))\n\n    @Ignore\n    @Test\n    fun `ten rows`() = assertTriangleEquals(\n            10,\n            listOf(\n                    listOf(1),\n                    listOf(1, 1),\n                    listOf(1, 2, 1),\n                    listOf(1, 3, 3, 1),\n                    listOf(1, 4, 6, 4, 1),\n                    listOf(1, 5, 10, 10, 5, 1),\n                    listOf(1, 6, 15, 20, 15, 6, 1),\n                    listOf(1, 7, 21, 35, 35, 21, 7, 1),\n                    listOf(1, 8, 28, 56, 70, 56, 28, 8, 1),\n                    listOf(1, 9, 36, 84, 126, 126, 84, 36, 9, 1)))\n\n}\n\nprivate fun assertTriangleEquals(rows: Int, triangles: List<List<Int>>) =\n        assertEquals(triangles, PascalsTriangle.computeTriangle(rows))\n"
  },
  {
    "path": "exercises/practice/perfect-numbers/.docs/instructions.md",
    "content": "# Instructions\n\nDetermine if a number is perfect, abundant, or deficient based on Nicomachus' (60 - 120 CE) classification scheme for positive integers.\n\nThe Greek mathematician [Nicomachus][nicomachus] devised a classification scheme for positive integers, identifying each as belonging uniquely to the categories of [perfect](#perfect), [abundant](#abundant), or [deficient](#deficient) based on their [aliquot sum][aliquot-sum].\nThe _aliquot sum_ is defined as the sum of the factors of a number not including the number itself.\nFor example, the aliquot sum of `15` is `1 + 3 + 5 = 9`.\n\n## Perfect\n\nA number is perfect when it equals its aliquot sum.\nFor example:\n\n- `6` is a perfect number because `1 + 2 + 3 = 6`\n- `28` is a perfect number because `1 + 2 + 4 + 7 + 14 = 28`\n\n## Abundant\n\nA number is abundant when it is less than its aliquot sum.\nFor example:\n\n- `12` is an abundant number because `1 + 2 + 3 + 4 + 6 = 16`\n- `24` is an abundant number because `1 + 2 + 3 + 4 + 6 + 8 + 12 = 36`\n\n## Deficient\n\nA number is deficient when it is greater than its aliquot sum.\nFor example:\n\n- `8` is a deficient number because `1 + 2 + 4 = 7`\n- Prime numbers are deficient\n\n## Task\n\nImplement a way to determine whether a given number is [perfect](#perfect).\nDepending on your language track, you may also need to implement a way to determine whether a given number is [abundant](#abundant) or [deficient](#deficient).\n\n[nicomachus]: https://en.wikipedia.org/wiki/Nicomachus\n[aliquot-sum]: https://en.wikipedia.org/wiki/Aliquot_sum\n"
  },
  {
    "path": "exercises/practice/perfect-numbers/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/NaturalNumber.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/NaturalNumberTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/NaturalNumber.kt\"\n    ]\n  },\n  \"blurb\": \"Determine if a number is perfect, abundant, or deficient based on Nicomachus' (60 - 120 CE) classification scheme for positive integers.\",\n  \"source\": \"Taken from Chapter 2 of Functional Thinking by Neal Ford.\",\n  \"source_url\": \"https://www.oreilly.com/library/view/functional-thinking/9781449365509/\"\n}\n"
  },
  {
    "path": "exercises/practice/perfect-numbers/.meta/src/reference/kotlin/NaturalNumber.kt",
    "content": "\nenum class Classification {\n    DEFICIENT, PERFECT, ABUNDANT\n}\n\nfun classify(naturalNumber: Int): Classification {\n    require(naturalNumber > 0) { \"$naturalNumber is not a natural number\" }\n\n    val aliquotSum = naturalNumber.aliquotSum()\n    return when {\n        aliquotSum == naturalNumber -> Classification.PERFECT\n        aliquotSum > naturalNumber -> Classification.ABUNDANT\n        else -> Classification.DEFICIENT\n    }\n}\n\nfun Int.aliquotSum(): Int = (1 until this).filter { this % it == 0 }.sum()\n"
  },
  {
    "path": "exercises/practice/perfect-numbers/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# Smallest perfect number is classified correctly\n\"163e8e86-7bfd-4ee2-bd68-d083dc3381a3\" = true\n\n# Medium perfect number is classified correctly\n\"169a7854-0431-4ae0-9815-c3b6d967436d\" = true\n\n# Large perfect number is classified correctly\n\"ee3627c4-7b36-4245-ba7c-8727d585f402\" = true\n\n# Smallest abundant number is classified correctly\n\"80ef7cf8-9ea8-49b9-8b2d-d9cb3db3ed7e\" = true\n\n# Medium abundant number is classified correctly\n\"3e300e0d-1a12-4f11-8c48-d1027165ab60\" = true\n\n# Large abundant number is classified correctly\n\"ec7792e6-8786-449c-b005-ce6dd89a772b\" = true\n\n# Smallest prime deficient number is classified correctly\n\"e610fdc7-2b6e-43c3-a51c-b70fb37413ba\" = true\n\n# Smallest non-prime deficient number is classified correctly\n\"0beb7f66-753a-443f-8075-ad7fbd9018f3\" = true\n\n# Medium deficient number is classified correctly\n\"1c802e45-b4c6-4962-93d7-1cad245821ef\" = true\n\n# Large deficient number is classified correctly\n\"47dd569f-9e5a-4a11-9a47-a4e91c8c28aa\" = true\n\n# Edge case (no factors other than itself) is classified correctly\n\"a696dec8-6147-4d68-afad-d38de5476a56\" = true\n\n# Zero is rejected (not a natural number)\n\"72445cee-660c-4d75-8506-6c40089dc302\" = true\n\n# Negative integer is rejected (not a natural number)\n\"2d72ce2c-6802-49ac-8ece-c790ba3dae13\" = true\n"
  },
  {
    "path": "exercises/practice/perfect-numbers/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/perfect-numbers/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/perfect-numbers/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/perfect-numbers/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/perfect-numbers/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/perfect-numbers/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/perfect-numbers/src/main/kotlin/NaturalNumber.kt",
    "content": "\nenum class Classification {\n    DEFICIENT, PERFECT, ABUNDANT\n}\n\nfun classify(naturalNumber: Int): Classification {\n    return Classification.DEFICIENT\n}\n"
  },
  {
    "path": "exercises/practice/perfect-numbers/src/test/kotlin/NaturalNumberTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\n\nimport org.junit.Assert.assertEquals\n\nclass NaturalNumberTest {\n\n    @Test\n    fun smallPerfectNumberIsClassifiedCorrectly() {\n        assertEquals(Classification.PERFECT, classify(6))\n    }\n\n    @Ignore\n    @Test\n    fun mediumPerfectNumberIsClassifiedCorrectly() {\n        assertEquals(Classification.PERFECT, classify(28))\n    }\n\n    @Ignore\n    @Test\n    fun largePerfectNumberIsClassifiedCorrectly() {\n        assertEquals(Classification.PERFECT, classify(33550336))\n    }\n\n    @Ignore\n    @Test\n    fun smallAbundantNumberIsClassifiedCorrectly() {\n        assertEquals(Classification.ABUNDANT, classify(12))\n    }\n\n    @Ignore\n    @Test\n    fun mediumAbundantNumberIsClassifiedCorrectly() {\n        assertEquals(Classification.ABUNDANT, classify(30))\n    }\n\n    @Ignore\n    @Test\n    fun largeAbundantNumberIsClassifiedCorrectly() {\n        assertEquals(Classification.ABUNDANT, classify(33550335))\n    }\n\n    @Ignore\n    @Test\n    fun smallestPrimeDeficientNumberIsClassifiedCorrectly() {\n        assertEquals(Classification.DEFICIENT, classify(2))\n    }\n\n    @Ignore\n    @Test\n    fun smallestNonPrimeDeficientNumberIsClassifiedCorrectly() {\n        assertEquals(Classification.DEFICIENT, classify(4))\n    }\n\n    @Ignore\n    @Test\n    fun mediumNumberIsClassifiedCorrectly() {\n        assertEquals(Classification.DEFICIENT, classify(32))\n    }\n\n    @Ignore\n    @Test\n    fun largeDeficientNumberIsClassifiedCorrectly() {\n        assertEquals(Classification.DEFICIENT, classify(33550337))\n    }\n\n    @Ignore\n    @Test\n    fun edgeCaseWithNoFactorsOtherThanItselfIsClassifiedCorrectly() {\n        assertEquals(Classification.DEFICIENT, classify(1))\n    }\n\n    @Ignore\n    @Test(expected = RuntimeException::class)\n    fun zeroIsNotANaturalNumber() {\n        classify(0)\n    }\n\n    @Ignore\n    @Test(expected = RuntimeException::class)\n    fun negativeNumberIsNotANaturalNumber() {\n        classify(-1)\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/phone-number/.docs/instructions.md",
    "content": "# Instructions\n\nClean up user-entered phone numbers so that they can be sent SMS messages.\n\nThe **North American Numbering Plan (NANP)** is a telephone numbering system used by many countries in North America like the United States, Canada or Bermuda.\nAll NANP-countries share the same international country code: `1`.\n\nNANP numbers are ten-digit numbers consisting of a three-digit Numbering Plan Area code, commonly known as _area code_, followed by a seven-digit local number.\nThe first three digits of the local number represent the _exchange code_, followed by the unique four-digit number which is the _subscriber number_.\n\nThe format is usually represented as\n\n```text\nNXX NXX-XXXX\n```\n\nwhere `N` is any digit from 2 through 9 and `X` is any digit from 0 through 9.\n\nSometimes they also have the country code (represented as `1` or `+1`) prefixed.\n\nYour task is to clean up differently formatted telephone numbers by removing punctuation and the country code if present.\n\nFor example, the inputs\n\n- `+1 (613)-995-0253`\n- `613-995-0253`\n- `1 613 995 0253`\n- `613.995.0253`\n\nshould all produce the output\n\n`6139950253`\n\n**Note:** As this exercise only deals with telephone numbers used in NANP-countries, only 1 is considered a valid country code.\n"
  },
  {
    "path": "exercises/practice/phone-number/.docs/introduction.md",
    "content": "# Introduction\n\nYou've joined LinkLine, a leading communications company working to ensure reliable connections for everyone.\nThe team faces a big challenge: users submit phone numbers in all sorts of formats — dashes, spaces, dots, parentheses, and even prefixes.\nSome numbers are valid, while others are impossible to use.\n\nYour mission is to turn this chaos into order.\nYou'll clean up valid numbers, formatting them appropriately for use in the system.\nAt the same time, you'll identify and filter out any invalid entries.\n\nThe success of LinkLine's operations depends on your ability to separate the useful from the unusable.\nAre you ready to take on the challenge and keep the connections running smoothly?\n"
  },
  {
    "path": "exercises/practice/phone-number/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"beatbrot\",\n    \"carpeliam\",\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/PhoneNumber.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/PhoneNumberTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/PhoneNumber.kt\"\n    ]\n  },\n  \"blurb\": \"Clean up user-entered phone numbers so that they can be sent SMS messages.\",\n  \"source\": \"Exercise by the JumpstartLab team for students at The Turing School of Software and Design.\",\n  \"source_url\": \"https://turing.edu\"\n}\n"
  },
  {
    "path": "exercises/practice/phone-number/.meta/src/reference/kotlin/PhoneNumber.kt",
    "content": "data class PhoneNumber(private val rawNumber: String) {\n\n    companion object {\n        private val invalidChars = Regex(\"[^\\\\d() -.]\")\n        private val digitsValidationRegex = Regex(\"^1?([2-9]\\\\d{2}[2-9]\\\\d{6})$\")\n    }\n\n    val number: String?\n\n    init {\n        require(!invalidChars.containsMatchIn(rawNumber))\n        number = pure() ?: throw  IllegalArgumentException()\n    }\n\n    private fun pure(): String? {\n        val digits = rawNumber.replace(Regex(\"[^\\\\d]\"), \"\")\n        return digitsValidationRegex.matchEntire(digits)?.groupValues?.last()\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/phone-number/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# cleans the number\n\"79666dce-e0f1-46de-95a1-563802913c35\" = true\n\n# cleans numbers with dots\n\"c360451f-549f-43e4-8aba-fdf6cb0bf83f\" = true\n\n# cleans numbers with multiple spaces\n\"08f94c34-9a37-46a2-a123-2a8e9727395d\" = true\n\n# invalid when 9 digits\n\"598d8432-0659-4019-a78b-1c6a73691d21\" = true\n\n# invalid when 11 digits does not start with a 1\n\"57061c72-07b5-431f-9766-d97da7c4399d\" = true\n\n# valid when 11 digits and starting with 1\n\"9962cbf3-97bb-4118-ba9b-38ff49c64430\" = true\n\n# valid when 11 digits and starting with 1 even with punctuation\n\"fa724fbf-054c-4d91-95da-f65ab5b6dbca\" = true\n\n# invalid when more than 11 digits\n\"c6a5f007-895a-4fc5-90bc-a7e70f9b5cad\" = true\n\n# invalid with letters\n\"63f38f37-53f6-4a5f-bd86-e9b404f10a60\" = true\n\n# invalid with punctuations\n\"4bd97d90-52fd-45d3-b0db-06ab95b1244e\" = true\n\n# invalid if area code starts with 0\n\"d77d07f8-873c-4b17-8978-5f66139bf7d7\" = true\n\n# invalid if area code starts with 1\n\"c7485cfb-1e7b-4081-8e96-8cdb3b77f15e\" = true\n\n# invalid if exchange code starts with 0\n\"4d622293-6976-413d-b8bf-dd8a94d4e2ac\" = true\n\n# invalid if exchange code starts with 1\n\"4cef57b4-7d8e-43aa-8328-1e1b89001262\" = true\n\n# invalid if area code starts with 0 on valid 11-digit number\n\"9925b09c-1a0d-4960-a197-5d163cbe308c\" = true\n\n# invalid if area code starts with 1 on valid 11-digit number\n\"3f809d37-40f3-44b5-ad90-535838b1a816\" = true\n\n# invalid if exchange code starts with 0 on valid 11-digit number\n\"e08e5532-d621-40d4-b0cc-96c159276b65\" = true\n\n# invalid if exchange code starts with 1 on valid 11-digit number\n\"57b32f3d-696a-455c-8bf1-137b6d171cdf\" = true\n"
  },
  {
    "path": "exercises/practice/phone-number/.meta/version",
    "content": "1.7.0\n"
  },
  {
    "path": "exercises/practice/phone-number/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/phone-number/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/phone-number/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/phone-number/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/phone-number/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/phone-number/src/main/kotlin/PhoneNumber.kt",
    "content": "class PhoneNumber {\n\n    // TODO: Implement proper constructor\n\n    val number: String? = TODO(\"Implement this getter to complete the task\")\n}\n"
  },
  {
    "path": "exercises/practice/phone-number/src/test/kotlin/PhoneNumberTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport java.lang.IllegalArgumentException\nimport kotlin.test.assertEquals\nimport kotlin.test.assertNull\n\nclass PhoneNumberTest {\n\n    @Test\n    fun `valid - simple number`() = assertNumberEquals(\"(223) 456-7890\", \"2234567890\")\n\n    @Ignore\n    @Test\n    fun `valid - number with dots`() = assertNumberEquals(\"223.456.7890\", \"2234567890\")\n\n    @Ignore\n    @Test\n    fun `valid - numbers with multiple spaces`() = assertNumberEquals(\"223 456   7890   \", \"2234567890\")\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid - 9 digit`() {\n        PhoneNumber(\"123456789\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid - when 11 digits does not start with a 1`() {\n        PhoneNumber(\"22234567890\")\n    }\n\n    @Ignore\n    @Test\n    fun `valid - 11 digits and starting with 1`() = assertNumberEquals(\"12234567890\", \"2234567890\")\n\n    @Ignore\n    @Test\n    fun `valid - 11 digits starting with 1 with punctuation`() = assertNumberEquals(\"+1 (223) 456-7890\", \"2234567890\")\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid - more than 11 digits`() {\n        PhoneNumber(\"321234567890\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid - letters`() {\n        PhoneNumber(\"123-abc-7890\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid - punctuations`() {\n        PhoneNumber(\"123-@:!-7890\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid - area code starts with 0`() {\n        PhoneNumber(\"(023) 456-7890\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid - area code starts with 1`() {\n        PhoneNumber(\"(123) 456-7890\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid - exchange code starts with 0`() {\n        PhoneNumber(\"(223) 056-7890\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid - exchange code starts with 1`() {\n        PhoneNumber(\"(223) 156-7890\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid - area code starts with 0 on valid 11-digit number`() {\n        PhoneNumber(\"1 (023) 456-7890\")\n    }\n\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid - area code starts with 1 on valid 11-digit number`() {\n        PhoneNumber(\"1 (123) 456-7890\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid - exchange code starts with 0 on valid 11-digit number`() {\n        PhoneNumber(\"1 (223) 056-7890\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `invalid - exchange code starts with 1 on valid 11-digit number`() {\n        PhoneNumber(\"1 (223) 156-7890\")\n    }\n}\n\nprivate fun assertNumberEquals(input: String, expectation: String) = assertEquals(expectation, PhoneNumber(input).number)\n"
  },
  {
    "path": "exercises/practice/pig-latin/.approaches/config.json",
    "content": "{\n  \"introduction\": {\n    \"authors\": [\n      \"bobahop\"\n    ]\n  },\n  \"approaches\": [\n    {\n      \"uuid\": \"8fc23555-9445-452e-9982-c09b9716b6dc\",\n      \"slug\": \"hashset-lookup\",\n      \"title\": \"HashSet lookup\",\n      \"blurb\": \"Look up values in HashSets to return the answer.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "exercises/practice/pig-latin/.approaches/hashset-lookup/content.md",
    "content": "# `HashSet` lookup\n\n```kotlin\nobject PigLatin {\n    private val vowels = hashSetOf('a', 'e', 'i', 'o', 'u')\n    private val specials = hashSetOf(\"xr\", \"yt\")\n    private val vowels_y = hashSetOf('a', 'e', 'i', 'o', 'u', 'y')\n\n    fun translate(phrase: String): String {\n        return phrase.split(\" \").joinToString(separator = \" \") { piggyfy(it) }\n    }\n\n    private fun piggyfy(word: String): String {\n        if (vowels.contains(word[0]) || specials.contains(word.substring(0, 2))) return word + \"ay\"\n        for (pos in 1..word.length) {\n            val letter = word[pos]\n            if (vowels_y.contains(letter)) {\n                val posCalc = if (letter == 'u' && word[pos - 1] == 'q') pos + 1 else pos\n                return word.substring(posCalc) + word.substring(0, posCalc) + \"ay\"\n            }\n        }\n        return word\n    }\n}\n```\n\nAn [object declaration][object] is used to define `PigLatin` as essentially a [singleton][singleton] object instantiation of the class.\nThis is sufficient, since there is no object state that needs to change with each call of the `translate` method.\n\nThree [`private`][visibility] [`val`][variables]s are defined for the [`HashSet`][hashset]s, using the [`hashSetOf`][hashsetof] method.\n\nThe `translate` function is implemented by splitting the input `String` by a space, and then using the [`joinToString`][jointostring] method\nwith a space as the separator.\nThe [lambda][lambda] of `joinToString` uses the [`it`][it] keyword to refer to the single `String` parameter for the lambda, and passes that to the\n`piggyfy` function.\nThe `translate` function returns the rejoined input `String` as transformed by each word being processed by the `piggyfy` function.\n\nThe `piggyfy` function takes the input `String` and checks to see if its first character is in the `HashSet` of vowels (not including `y`) or\nif the first two characters are in the `HashSet` of \"specials\" (e.g. `\"xr\"` or `\"yt\"`).\nIf the word starts with a vowel or a special two-letter combination, then the function returns the word concatenated with `ay` at the end.\n\nOtherwise, a [range][range] is used to iterate an index for the characters of the word in a [`for`][for-loop] loop,\nstarting with the second character and up to but not including the length of the word.\n\nA variable is set from the character in the word at the current index of the range.\n\nIf the character is in the `HashSet` of vowels (including `y`), then the index is adjusted if the current character is a `u`\nand the previous character is a `q`.\nA [`substring`][substring] is then taken from the character at the index until the end of the word.\nConcatenated to the end of that is a `substring` from the beginning of the word up to but not including the index.\nFinally, concatenated to the end of that is `ay`.\nThe concatenated `String` is returned from the function.\n\nIn the event that the word has no vowels and the `for` loop finishes without returning, the function returns the word as is.\n\n[object]: https://kotlinlang.org/docs/object-declarations.html#object-declarations-overview\n[singleton]: https://en.wikipedia.org/wiki/Singleton_pattern\n[visibility]: https://kotlinlang.org/docs/visibility-modifiers.html\n[variables]: https://kotlinlang.org/docs/basic-syntax.html#variables\n[hashset]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-hash-set/\n[hashsetof]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/hash-set-of.html\n[jointostring]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/join-to-string.html\n[lambda]: https://kotlinlang.org/docs/lambdas.html#lambda-expressions-and-anonymous-functions\n[it]: https://kotlinlang.org/docs/lambdas.html#it-implicit-name-of-a-single-parameter\n[range]: https://kotlinlang.org/docs/ranges.html\n[for-loop]: https://kotlinlang.org/docs/control-flow.html#for-loops\n[substring]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/substring.html\n"
  },
  {
    "path": "exercises/practice/pig-latin/.approaches/hashset-lookup/snippet.txt",
    "content": "if (vowels.contains(word[0]) || specials.contains(word.substring(0, 2))) return word + \"ay\"\nfor (pos in 1..word.length) {\n    val letter = word[pos]\n    if (vowels_y.contains(letter)) {\n        val posCalc = if (letter == 'u' && word[pos - 1] == 'q') pos + 1 else pos\n        return word.substring(posCalc) + word.substring(0, posCalc) + \"ay\"\n    }\n}\n"
  },
  {
    "path": "exercises/practice/pig-latin/.approaches/introduction.md",
    "content": "# Introduction\n\nThere are many ways to solve Pig Latin.\nOne approach is to look up values from [HashSet][hashset]s.\n\n## General guidance\n\nAt the time of writing only four rules need to be handled, but if they have similar output, they don't need to be handled completely separately.\n\n## Approach: `HashSet` lookup\n\n```kotlin\nobject PigLatin {\n    private val vowels = hashSetOf('a', 'e', 'i', 'o', 'u')\n    private val specials = hashSetOf(\"xr\", \"yt\")\n    private val vowels_y = hashSetOf('a', 'e', 'i', 'o', 'u', 'y')\n\n    fun translate(phrase: String): String {\n        return phrase.split(\" \").joinToString(separator = \" \") { piggyfy(it) }\n    }\n\n    private fun piggyfy(word: String): String {\n        if (vowels.contains(word[0]) || specials.contains(word.substring(0, 2))) return word + \"ay\"\n        for (pos in 1..word.length) {\n            val letter = word[pos]\n            if (vowels_y.contains(letter)) {\n                val posCalc = if (letter == 'u' && word[pos - 1] == 'q') pos + 1 else pos\n                return word.substring(posCalc) + word.substring(0, posCalc) + \"ay\"\n            }\n        }\n        return word\n    }\n}\n```\n\nFor more information, check the [`HashSet` lookup approach][approach-hashset-lookup].\n\n[approach-hashset-lookup]: https://exercism.org/tracks/kotlin/exercises/pig-latin/approaches/hashset-lookup\n[hashset]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-hash-set/\n"
  },
  {
    "path": "exercises/practice/pig-latin/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to translate text from English to Pig Latin.\nThe translation is defined using four rules, which look at the pattern of vowels and consonants at the beginning of a word.\nThese rules look at each word's use of vowels and consonants:\n\n- vowels: the letters `a`, `e`, `i`, `o`, and `u`\n- consonants: the other 21 letters of the English alphabet\n\n## Rule 1\n\nIf a word begins with a vowel, or starts with `\"xr\"` or `\"yt\"`, add an `\"ay\"` sound to the end of the word.\n\nFor example:\n\n- `\"apple\"` -> `\"appleay\"` (starts with vowel)\n- `\"xray\"` -> `\"xrayay\"` (starts with `\"xr\"`)\n- `\"yttria\"` -> `\"yttriaay\"` (starts with `\"yt\"`)\n\n## Rule 2\n\nIf 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.\n\nFor example:\n\n- `\"pig\"` -> `\"igp\"` -> `\"igpay\"` (starts with single consonant)\n- `\"chair\"` -> `\"airch\"` -> `\"airchay\"` (starts with multiple consonants)\n- `\"thrush\"` -> `\"ushthr\"` -> `\"ushthray\"` (starts with multiple consonants)\n\n## Rule 3\n\nIf 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.\n\nFor example:\n\n- `\"quick\"` -> `\"ickqu\"` -> `\"ickquay\"` (starts with `\"qu\"`, no preceding consonants)\n- `\"square\"` -> `\"aresqu\"` -> `\"aresquay\"` (starts with one consonant followed by `\"qu`\")\n\n## Rule 4\n\nIf 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.\n\nSome examples:\n\n- `\"my\"` -> `\"ym\"` -> `\"ymay\"` (starts with single consonant followed by `\"y\"`)\n- `\"rhythm\"` -> `\"ythmrh\"` -> `\"ythmrhay\"` (starts with multiple consonants followed by `\"y\"`)\n"
  },
  {
    "path": "exercises/practice/pig-latin/.docs/introduction.md",
    "content": "# Introduction\n\nYour parents have challenged you and your sibling to a game of two-on-two basketball.\nConfident they'll win, they let you score the first couple of points, but then start taking over the game.\nNeeding 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.\nThis will give you the edge to prevail over your parents!\n\n[pig-latin]: https://en.wikipedia.org/wiki/Pig_latin\n"
  },
  {
    "path": "exercises/practice/pig-latin/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/PigLatin.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/PigLatinTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/PigLatin.kt\"\n    ]\n  },\n  \"blurb\": \"Implement a program that translates from English to Pig Latin.\",\n  \"source\": \"The Pig Latin exercise at Test First Teaching by Ultrasaurus\",\n  \"source_url\": \"https://github.com/ultrasaurus/test-first-teaching/blob/master/learn_ruby/pig_latin/\"\n}\n"
  },
  {
    "path": "exercises/practice/pig-latin/.meta/src/reference/kotlin/PigLatin.kt",
    "content": "object PigLatin {\n\n    fun translate(phrase: String) = phrase.split(Regex(\"\\\\s+\")).joinToString(\" \") { translateWord(it) }\n\n    private fun translateWord(word: String): String {\n        if (startsWithVowelSound(word)) {\n            return word + \"ay\"\n        }\n\n        val groups = splitInitialConsonantSound(word)\n        if(groups != null) {\n            return groups[1] + groups[0] + \"ay\"\n        }\n\n        return word\n    }\n\n    private val consonant = Regex(\"^([^aeiou]?qu|[^aeiouy]+|[^aeiou]+)([a-z]*)\", RegexOption.IGNORE_CASE)\n    private fun splitInitialConsonantSound(word: String) = consonant.matchEntire(word)?.groupValues?.drop(1)\n\n    private val vowels = Regex(\"^([aeiou]|y[^aeiou]|xr)[a-z]*\", RegexOption.IGNORE_CASE)\n    private fun startsWithVowelSound(word: String) = vowels.matches(word)\n\n}\n"
  },
  {
    "path": "exercises/practice/pig-latin/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# word beginning with a\n\"11567f84-e8c6-4918-aedb-435f0b73db57\" = true\n\n# word beginning with e\n\"f623f581-bc59-4f45-9032-90c3ca9d2d90\" = true\n\n# word beginning with i\n\"7dcb08b3-23a6-4e8a-b9aa-d4e859450d58\" = true\n\n# word beginning with o\n\"0e5c3bff-266d-41c8-909f-364e4d16e09c\" = true\n\n# word beginning with u\n\"614ba363-ca3c-4e96-ab09-c7320799723c\" = true\n\n# word beginning with a vowel and followed by a qu\n\"bf2538c6-69eb-4fa7-a494-5a3fec911326\" = true\n\n# word beginning with p\n\"e5be8a01-2d8a-45eb-abb4-3fcc9582a303\" = true\n\n# word beginning with k\n\"d36d1e13-a7ed-464d-a282-8820cb2261ce\" = true\n\n# word beginning with x\n\"d838b56f-0a89-4c90-b326-f16ff4e1dddc\" = true\n\n# word beginning with q without a following u\n\"bce94a7a-a94e-4e2b-80f4-b2bb02e40f71\" = true\n\n# word beginning with ch\n\"c01e049a-e3e2-451c-bf8e-e2abb7e438b8\" = true\n\n# word beginning with qu\n\"9ba1669e-c43f-4b93-837a-cfc731fd1425\" = true\n\n# word beginning with qu and a preceding consonant\n\"92e82277-d5e4-43d7-8dd3-3a3b316c41f7\" = true\n\n# word beginning with th\n\"79ae4248-3499-4d5b-af46-5cb05fa073ac\" = true\n\n# word beginning with thr\n\"e0b3ae65-f508-4de3-8999-19c2f8e243e1\" = true\n\n# word beginning with sch\n\"20bc19f9-5a35-4341-9d69-1627d6ee6b43\" = true\n\n# word beginning with yt\n\"54b796cb-613d-4509-8c82-8fbf8fc0af9e\" = true\n\n# word beginning with xr\n\"8c37c5e1-872e-4630-ba6e-d20a959b67f6\" = true\n\n# y is treated like a consonant at the beginning of a word\n\"a4a36d33-96f3-422c-a233-d4021460ff00\" = true\n\n# y is treated like a vowel at the end of a consonant cluster\n\"adc90017-1a12-4100-b595-e346105042c7\" = true\n\n# y as second letter in two letter word\n\"29b4ca3d-efe5-4a95-9a54-8467f2e5e59a\" = true\n\n# a whole phrase\n\"44616581-5ce3-4a81-82d0-40c7ab13d2cf\" = true\n"
  },
  {
    "path": "exercises/practice/pig-latin/.meta/version",
    "content": "1.2.0\n"
  },
  {
    "path": "exercises/practice/pig-latin/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/pig-latin/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/pig-latin/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/pig-latin/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/pig-latin/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/pig-latin/src/main/kotlin/PigLatin.kt",
    "content": "object PigLatin {\n\n    fun translate(phrase: String): String {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/pig-latin/src/test/kotlin/PigLatinTest.kt",
    "content": "import org.junit.Test\nimport org.junit.runner.RunWith\nimport org.junit.runners.Parameterized\nimport kotlin.test.assertEquals\n\n@RunWith(Parameterized::class)\nclass PigLatinTest(val input: String, val expectedOutput: String) {\n\n    companion object {\n        @JvmStatic\n        @Parameterized.Parameters(name = \"{index}: translate({0})={1}\")\n        fun data() = arrayOf(\n                // Ay is added to words that start with vowels\n                arrayOf(\"apple\",  \"appleay\"),\n                arrayOf(\"ear\",    \"earay\"),\n                arrayOf(\"igloo\",  \"iglooay\"),\n                arrayOf(\"object\", \"objectay\"),\n                arrayOf(\"under\",  \"underay\"),\n\n                // Ay is added to words that start with vowels followed by qu\n                arrayOf(\"equal\",  \"equalay\"),\n\n                // First letter and ay are moved to the end of words that start with consonants\n                arrayOf(\"pig\",    \"igpay\"),\n                arrayOf(\"koala\",  \"oalakay\"),\n                arrayOf(\"xenon\",  \"enonxay\"),\n                arrayOf(\"qat\",    \"atqay\"),\n\n                // Ch is treated like a single consonant\n                arrayOf(\"chair\", \"airchay\"),\n\n                // Qu is treated like a single consonant\n                arrayOf(\"queen\", \"eenquay\"),\n\n                // Qu and a single preceding consonant are treated like a single consonant\n                arrayOf(\"square\", \"aresquay\"),\n\n                // Th is treated like a single consonant\n                arrayOf(\"therapy\", \"erapythay\"),\n\n                // Thr is treated like a single consonant\n                arrayOf(\"thrush\", \"ushthray\"),\n\n                // Sch is treated like a single consonant\n                arrayOf(\"school\", \"oolschay\"),\n\n                // Yt is treated like a single vowel\n                arrayOf(\"yttria\", \"yttriaay\"),\n\n                // Xr is treated like a single vowel\n                arrayOf(\"xray\", \"xrayay\"),\n\n                // Y is treated like a consonant at the beginning of a word\n                arrayOf(\"yellow\", \"ellowyay\"),\n\n                // Y is treated like a vowel at the end of a consonant cluster\n                arrayOf(\"rhythm\", \"ythmrhay\"),\n\n                // Y as second letter in two letter word\n                arrayOf(\"my\",     \"ymay\"),\n\n                // Phrases are translated\n                arrayOf(\"quick fast run\", \"ickquay astfay unray\")\n        )\n    }\n\n    @Test\n    fun test() {\n        assertEquals(expectedOutput, PigLatin.translate(input))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/prime-factors/.docs/instructions.md",
    "content": "# Instructions\n\nCompute the prime factors of a given natural number.\n\nA prime number is only evenly divisible by itself and 1.\n\nNote that 1 is not a prime number.\n\n## Example\n\nWhat are the prime factors of 60?\n\n- Our first divisor is 2.\n  2 goes into 60, leaving 30.\n- 2 goes into 30, leaving 15.\n  - 2 doesn't go cleanly into 15.\n    So let's move on to our next divisor, 3.\n- 3 goes cleanly into 15, leaving 5.\n  - 3 does not go cleanly into 5.\n    The next possible factor is 4.\n  - 4 does not go cleanly into 5.\n    The next possible factor is 5.\n- 5 does go cleanly into 5.\n- We're left only with 1, so now, we're done.\n\nOur successful divisors in that computation represent the list of prime factors of 60: 2, 2, 3, and 5.\n\nYou can check this yourself:\n\n```text\n2 * 2 * 3 * 5\n= 4 * 15\n= 60\n```\n\nSuccess!\n"
  },
  {
    "path": "exercises/practice/prime-factors/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/PrimeFactors.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/PrimeFactorCalculatorTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/PrimeFactors.kt\"\n    ]\n  },\n  \"blurb\": \"Compute the prime factors of a given natural number.\",\n  \"source\": \"The Prime Factors Kata by Uncle Bob\",\n  \"source_url\": \"https://web.archive.org/web/20221026171801/http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata\"\n}\n"
  },
  {
    "path": "exercises/practice/prime-factors/.meta/src/reference/kotlin/PrimeFactors.kt",
    "content": "object PrimeFactorCalculator {\n\n    fun primeFactors(int: Int): List<Int> {\n        return primeFactors(int.toLong()).map(Long::toInt)\n    }\n\n    fun primeFactors(long: Long): List<Long> {\n        val result = mutableListOf<Long>()\n        var remainder = long\n        var divisor: Long = 2\n\n        while (remainder > 1) {\n            while (remainder.rem(divisor) == 0L) {\n                result.add(divisor)\n                remainder /= divisor\n            }\n\n            divisor++\n        }\n\n        return result\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/prime-factors/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# no factors\n\"924fc966-a8f5-4288-82f2-6b9224819ccd\" = true\n\n# prime number\n\"17e30670-b105-4305-af53-ddde182cb6ad\" = true\n\n# square of a prime\n\"f59b8350-a180-495a-8fb1-1712fbee1158\" = true\n\n# cube of a prime\n\"bc8c113f-9580-4516-8669-c5fc29512ceb\" = true\n\n# product of primes and non-primes\n\"00485cd3-a3fe-4fbe-a64a-a4308fc1f870\" = true\n\n# product of primes\n\"02251d54-3ca1-4a9b-85e1-b38f4b0ccb91\" = true\n\n# factors include a large prime\n\"070cf8dc-e202-4285-aa37-8d775c9cd473\" = true\n"
  },
  {
    "path": "exercises/practice/prime-factors/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/prime-factors/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/prime-factors/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/prime-factors/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/prime-factors/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/prime-factors/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/prime-factors/src/main/kotlin/PrimeFactors.kt",
    "content": "object PrimeFactorCalculator {\n\n    fun primeFactors(int: Int): List<Int> {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun primeFactors(long: Long): List<Long> {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/prime-factors/src/test/kotlin/PrimeFactorCalculatorTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass PrimeFactorCalculatorTest {\n\n    @Test\n    fun testThat1HasNoPrimeFactors() {\n        assertEquals(emptyList(), PrimeFactorCalculator.primeFactors(1))\n    }\n\n    @Ignore\n    @Test\n    fun testThatAPrimeNumberHasExactlyOnePrimeFactor() {\n        assertEquals(listOf(2), PrimeFactorCalculator.primeFactors(2))\n    }\n\n    @Ignore\n    @Test\n    fun testThatASquareOfAPrimeHasExactlyOnePrimeFactorRepeatedTwice() {\n        assertEquals(listOf(3, 3), PrimeFactorCalculator.primeFactors(9))\n    }\n\n    @Ignore\n    @Test\n    fun testThatACubeOfAPrimeHasExactlyOnePrimeFactorRepeatedThreeTimes() {\n        assertEquals(listOf(2, 2, 2), PrimeFactorCalculator.primeFactors(8))\n    }\n\n    @Ignore\n    @Test\n    fun testThatAProductOfPrimesAndNonPrimesIsFactoredProperly() {\n        assertEquals(listOf(2, 2, 3), PrimeFactorCalculator.primeFactors(12))\n    }\n\n    @Ignore\n    @Test\n    fun testThatAProductOfSmallPrimesIsFactoredProperly() {\n        assertEquals(listOf(5, 17, 23, 461), PrimeFactorCalculator.primeFactors(901255))\n    }\n\n    @Ignore\n    @Test\n    fun testThatAProductOfSmallAndLargePrimesIsFactoredProperly() {\n        assertEquals(listOf<Long>(11, 9539, 894119), PrimeFactorCalculator.primeFactors(93819012551L))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/protein-translation/.docs/instructions.md",
    "content": "# Instructions\n\nTranslate RNA sequences into proteins.\n\nRNA can be broken into three-nucleotide sequences called codons, and then translated to a protein like so:\n\nRNA: `\"AUGUUUUCU\"` => translates to\n\nCodons: `\"AUG\", \"UUU\", \"UCU\"`\n=> which become a protein with the following sequence =>\n\nProtein: `\"Methionine\", \"Phenylalanine\", \"Serine\"`\n\nThere are 64 codons which in turn correspond to 20 amino acids; however, all of the codon sequences and resulting amino acids are not important in this exercise.\nIf it works for one codon, the program should work for all of them.\nHowever, feel free to expand the list in the test suite to include them all.\n\nThere are also three terminating codons (also known as 'STOP' codons); if any of these codons are encountered (by the ribosome), all translation ends and the protein is terminated.\n\nAll subsequent codons after are ignored, like this:\n\nRNA: `\"AUGUUUUCUUAAAUG\"` =>\n\nCodons: `\"AUG\", \"UUU\", \"UCU\", \"UAA\", \"AUG\"` =>\n\nProtein: `\"Methionine\", \"Phenylalanine\", \"Serine\"`\n\nNote the stop codon `\"UAA\"` terminates the translation and the final methionine is not translated into the protein sequence.\n\nBelow are the codons and resulting amino acids needed for the exercise.\n\n| Codon              | Amino Acid    |\n| :----------------- | :------------ |\n| AUG                | Methionine    |\n| UUU, UUC           | Phenylalanine |\n| UUA, UUG           | Leucine       |\n| UCU, UCC, UCA, UCG | Serine        |\n| UAU, UAC           | Tyrosine      |\n| UGU, UGC           | Cysteine      |\n| UGG                | Tryptophan    |\n| UAA, UAG, UGA      | STOP          |\n\nLearn more about [protein translation on Wikipedia][protein-translation].\n\n[protein-translation]: https://en.wikipedia.org/wiki/Translation_(biology)\n"
  },
  {
    "path": "exercises/practice/protein-translation/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"AnneKlapwijk\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/ProteinTranslation.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ProteinTranslationTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/ProteinTranslation.kt\"\n    ]\n  },\n  \"blurb\": \"Translate RNA sequences into proteins.\",\n  \"source\": \"Tyler Long\"\n}\n"
  },
  {
    "path": "exercises/practice/protein-translation/.meta/src/reference/kotlin/ProteinTranslation.kt",
    "content": "fun translate(rna: String?): List<String> {\n    if (rna.isNullOrBlank()) return emptyList()\n\n    val codons = rna.chunked(3)\n    val stopIndex = codons.indexOfFirst { listOf(\"UAA\", \"UAG\", \"UGA\").contains(it) }\n\n    return codons.subList(0, if (stopIndex > -1) stopIndex else codons.size).map { codon ->\n        when (codon) {\n            \"AUG\" -> \"Methionine\"\n            \"UUU\", \"UUC\" -> \"Phenylalanine\"\n            \"UUA\", \"UUG\" -> \"Leucine\"\n            \"UCU\", \"UCC\", \"UCA\", \"UCG\" -> \"Serine\"\n            \"UAU\", \"UAC\" -> \"Tyrosine\"\n            \"UGU\", \"UGC\" -> \"Cysteine\"\n            \"UGG\" -> \"Tryptophan\"\n            else -> throw IllegalArgumentException(\"Invalid codon\")\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/protein-translation/.meta/tests.toml",
    "content": "# This is an auto-generated file.\n#\n# Regenerating this file via `configlet sync` will:\n# - Recreate every `description` key/value pair\n# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications\n# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)\n# - Preserve any other key/value pair\n#\n# As user-added comments (using the # character) will be removed when this file\n# is regenerated, comments can be added via a `comment` key.\n\n[2c44f7bf-ba20-43f7-a3bf-f2219c0c3f98]\ndescription = \"Empty RNA sequence results in no proteins\"\n\n[96d3d44f-34a2-4db4-84cd-fff523e069be]\ndescription = \"Methionine RNA sequence\"\n\n[1b4c56d8-d69f-44eb-be0e-7b17546143d9]\ndescription = \"Phenylalanine RNA sequence 1\"\n\n[81b53646-bd57-4732-b2cb-6b1880e36d11]\ndescription = \"Phenylalanine RNA sequence 2\"\n\n[42f69d4f-19d2-4d2c-a8b0-f0ae9ee1b6b4]\ndescription = \"Leucine RNA sequence 1\"\n\n[ac5edadd-08ed-40a3-b2b9-d82bb50424c4]\ndescription = \"Leucine RNA sequence 2\"\n\n[8bc36e22-f984-44c3-9f6b-ee5d4e73f120]\ndescription = \"Serine RNA sequence 1\"\n\n[5c3fa5da-4268-44e5-9f4b-f016ccf90131]\ndescription = \"Serine RNA sequence 2\"\n\n[00579891-b594-42b4-96dc-7ff8bf519606]\ndescription = \"Serine RNA sequence 3\"\n\n[08c61c3b-fa34-4950-8c4a-133945570ef6]\ndescription = \"Serine RNA sequence 4\"\n\n[54e1e7d8-63c0-456d-91d2-062c72f8eef5]\ndescription = \"Tyrosine RNA sequence 1\"\n\n[47bcfba2-9d72-46ad-bbce-22f7666b7eb1]\ndescription = \"Tyrosine RNA sequence 2\"\n\n[3a691829-fe72-43a7-8c8e-1bd083163f72]\ndescription = \"Cysteine RNA sequence 1\"\n\n[1b6f8a26-ca2f-43b8-8262-3ee446021767]\ndescription = \"Cysteine RNA sequence 2\"\n\n[1e91c1eb-02c0-48a0-9e35-168ad0cb5f39]\ndescription = \"Tryptophan RNA sequence\"\n\n[e547af0b-aeab-49c7-9f13-801773a73557]\ndescription = \"STOP codon RNA sequence 1\"\n\n[67640947-ff02-4f23-a2ef-816f8a2ba72e]\ndescription = \"STOP codon RNA sequence 2\"\n\n[9c2ad527-ebc9-4ace-808b-2b6447cb54cb]\ndescription = \"STOP codon RNA sequence 3\"\n\n[f4d9d8ee-00a8-47bf-a1e3-1641d4428e54]\ndescription = \"Sequence of two protein codons translates into proteins\"\n\n[dd22eef3-b4f1-4ad6-bb0b-27093c090a9d]\ndescription = \"Sequence of two different protein codons translates into proteins\"\n\n[d0f295df-fb70-425c-946c-ec2ec185388e]\ndescription = \"Translate RNA strand into correct protein list\"\n\n[e30e8505-97ec-4e5f-a73e-5726a1faa1f4]\ndescription = \"Translation stops if STOP codon at beginning of sequence\"\n\n[5358a20b-6f4c-4893-bce4-f929001710f3]\ndescription = \"Translation stops if STOP codon at end of two-codon sequence\"\n\n[ba16703a-1a55-482f-bb07-b21eef5093a3]\ndescription = \"Translation stops if STOP codon at end of three-codon sequence\"\n\n[4089bb5a-d5b4-4e71-b79e-b8d1f14a2911]\ndescription = \"Translation stops if STOP codon in middle of three-codon sequence\"\n\n[2c2a2a60-401f-4a80-b977-e0715b23b93d]\ndescription = \"Translation stops if STOP codon in middle of six-codon sequence\"\n\n[1e75ea2a-f907-4994-ae5c-118632a1cb0f]\ndescription = \"Non-existing codon can't translate\"\n\n[9eac93f3-627a-4c90-8653-6d0a0595bc6f]\ndescription = \"Unknown amino acids, not part of a codon, can't translate\"\n\n[9d73899f-e68e-4291-b1e2-7bf87c00f024]\ndescription = \"Incomplete RNA sequence can't translate\"\n\n[43945cf7-9968-402d-ab9f-b8a28750b050]\ndescription = \"Incomplete RNA sequence can translate if valid until a STOP codon\"\n"
  },
  {
    "path": "exercises/practice/protein-translation/.meta/version",
    "content": "1.0.0\n"
  },
  {
    "path": "exercises/practice/protein-translation/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/protein-translation/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/protein-translation/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/protein-translation/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/protein-translation/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/protein-translation/src/main/kotlin/ProteinTranslation.kt",
    "content": "fun translate(rna: String?): List<String> {\n    TODO(\"Implement this function to complete the task\")\n}\n"
  },
  {
    "path": "exercises/practice/protein-translation/src/test/kotlin/ProteinTranslationTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport org.junit.runner.RunWith\nimport org.junit.runners.Parameterized\nimport kotlin.test.assertEquals\nimport kotlin.test.assertFailsWith\n\nclass ProteinTranslationTest {\n    @Test\n    fun emptyRNAHasNoProteins() {\n        assertEquals(emptyList(), translate(null))\n    }\n\n    @Ignore\n    @Test\n    fun `Sequence of two protein codons translates into proteins`() {\n        assertEquals(listOf(\"Phenylalanine\", \"Phenylalanine\"), translate(\"UUUUUU\"))\n    }\n\n    @Ignore\n    @Test\n    fun `Sequence of two different protein codons translates into proteins`() {\n        assertEquals(listOf(\"Leucine\", \"Leucine\"), translate(\"UUAUUG\"))\n    }\n\n    @Ignore\n    @Test\n    fun `Translate RNA strand into correct protein list`() {\n        assertEquals(listOf(\"Methionine\", \"Phenylalanine\", \"Tryptophan\"), translate(\"AUGUUUUGG\"))\n    }\n\n    @Ignore\n    @Test\n    fun `Translation stops if STOP codon at beginning of sequence`() {\n        assertEquals(emptyList(), translate(\"UAGUGG\"))\n    }\n\n    @Ignore\n    @Test\n    fun `Translation stops if STOP codon at end of three-codon sequence`() {\n        assertEquals(listOf(\"Methionine\", \"Phenylalanine\"), translate(\"AUGUUUUAA\"))\n    }\n\n    @Ignore\n    @Test\n    fun `Translation stops if STOP codon in middle of three-codon sequence`() {\n        assertEquals(listOf(\"Tryptophan\"), translate(\"UGGUAGUGG\"))\n    }\n\n    @Ignore\n    @Test\n    fun `Translation stops if STOP codon in middle of six-codon sequence`() {\n        assertEquals(listOf(\"Tryptophan\", \"Cysteine\", \"Tyrosine\"), translate(\"UGGUGUUAUUAAUGGUUU\"))\n    }\n\n    @Ignore\n    @Test\n    fun `Non-existing codon can't translate`() {\n        assertFailsWith<IllegalArgumentException>(\"Invalid codon\") {\n            translate(\"AAA\")\n        }\n    }\n\n    @Ignore\n    @Test\n    fun `Unknown amino acids, not part of a codon, can't translate`() {\n        assertFailsWith<IllegalArgumentException>(\"Invalid codon\") {\n            translate(\"XYZ\")\n        }\n    }\n\n    @Ignore\n    @Test\n    fun `Incomplete RNA sequence can't translate`() {\n        assertFailsWith<IllegalArgumentException>(\"Invalid codon\") {\n            translate(\"AUGU\")\n        }\n    }\n\n    @Ignore\n    @Test\n    fun `Incomplete RNA sequence can translate if valid until a STOP codon`() {\n        assertEquals(listOf(\"Phenylalanine\", \"Phenylalanine\"), translate(\"UUCUUCUAAUGGU\"))\n    }\n}\n\n@RunWith(Parameterized::class)\nclass ParameterizedProteinTranslationTest(private val protein: String, private val codons: List<String>) {\n    companion object {\n        @JvmStatic\n        @Parameterized.Parameters\n        fun data(): Collection<Array<Any>> {\n            return listOf(\n                    arrayOf(\"Methionine\", listOf(\"AUG\")),\n                    arrayOf(\"Phenylalanine\", listOf(\"UUU\", \"UUC\")),\n                    arrayOf(\"Leucine\", listOf(\"UUA\", \"UUG\")),\n                    arrayOf(\"Serine\", listOf(\"UCU\", \"UCC\", \"UCA\", \"UCG\")),\n                    arrayOf(\"Tyrosine\", listOf(\"UAU\", \"UAC\")),\n                    arrayOf(\"Cysteine\", listOf(\"UGU\", \"UGC\")),\n                    arrayOf(\"Tryptophan\", listOf(\"UGG\"))\n            )\n        }\n    }\n\n    @Ignore\n    @Test\n    fun `Protein codon translates into protein`() {\n        codons.forEachIndexed { index, codon ->\n            val seq = index + 1\n            assertEquals(listOf(protein), translate(codon), \"${protein} RNA sequence ${seq} translates into ${protein}\")\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/rail-fence-cipher/.docs/instructions.md",
    "content": "# Instructions\n\nImplement encoding and decoding for the rail fence cipher.\n\nThe Rail Fence cipher is a form of transposition cipher that gets its name from the way in which it's encoded.\nIt was already used by the ancient Greeks.\n\nIn 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).\nFinally the message is then read off in rows.\n\nFor example, using three \"rails\" and the message \"WE ARE DISCOVERED FLEE AT ONCE\", the cipherer writes out:\n\n```text\nW . . . E . . . C . . . R . . . L . . . T . . . E\n. E . R . D . S . O . E . E . F . E . A . O . C .\n. . A . . . I . . . V . . . D . . . E . . . N . .\n```\n\nThen reads off:\n\n```text\nWECRLTEERDSOEEFEAOCAIVDEN\n```\n\nTo decrypt a message you take the zig-zag shape and fill the ciphertext along the rows.\n\n```text\n? . . . ? . . . ? . . . ? . . . ? . . . ? . . . ?\n. ? . ? . ? . ? . ? . ? . ? . ? . ? . ? . ? . ? .\n. . ? . . . ? . . . ? . . . ? . . . ? . . . ? . .\n```\n\nThe first row has seven spots that can be filled with \"WECRLTE\".\n\n```text\nW . . . E . . . C . . . R . . . L . . . T . . . E\n. ? . ? . ? . ? . ? . ? . ? . ? . ? . ? . ? . ? .\n. . ? . . . ? . . . ? . . . ? . . . ? . . . ? . .\n```\n\nNow the 2nd row takes \"ERDSOEEFEAOC\".\n\n```text\nW . . . E . . . C . . . R . . . L . . . T . . . E\n. E . R . D . S . O . E . E . F . E . A . O . C .\n. . ? . . . ? . . . ? . . . ? . . . ? . . . ? . .\n```\n\nLeaving \"AIVDEN\" for the last row.\n\n```text\nW . . . E . . . C . . . R . . . L . . . T . . . E\n. E . R . D . S . O . E . E . F . E . A . O . C .\n. . A . . . I . . . V . . . D . . . E . . . N . .\n```\n\nIf you now read along the zig-zag shape you can read the original message.\n"
  },
  {
    "path": "exercises/practice/rail-fence-cipher/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"vmichalak\"\n  ],\n  \"contributors\": [\n    \"araknoid\",\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/RailFenceCipher.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/RailFenceCipherTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/RailFenceCipher.kt\"\n    ]\n  },\n  \"blurb\": \"Implement encoding and decoding for the rail fence cipher.\",\n  \"source\": \"Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Transposition_cipher#Rail_Fence_cipher\"\n}\n"
  },
  {
    "path": "exercises/practice/rail-fence-cipher/.meta/src/reference/kotlin/RailFenceCipher.kt",
    "content": "class RailFenceCipher(private val key: Int) {\n    private val size: Int = key * 2 - 2\n\n    fun getEncryptedData(input: String): String = input\n            .mapIndexed { i, c -> Pair(track(i), c) }\n            .groupBy { it.first }\n            .flatMap { it -> it.value.map { it.second } }\n            .joinToString(\"\")\n\n    fun getDecryptedData(input: String): String = (0 until input.length)\n            .groupBy { track(it) }\n            .flatMap { it.value }\n            .zip(input.asIterable())\n            .sortedBy { it.first }\n            .map { it.second }\n            .joinToString(\"\")\n\n    private fun track(index: Int) = when {\n        isCorrect(index) -> 0\n        isCorrect(index - key + 1) -> key -1\n        else -> (1 until key).first { isCorrect(index - it) || isCorrect(index - size + it)}\n    }\n\n    private fun isCorrect(index: Int): Boolean = index % size == 0\n}\n"
  },
  {
    "path": "exercises/practice/rail-fence-cipher/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# encode with two rails\n\"46dc5c50-5538-401d-93a5-41102680d068\" = true\n\n# encode with three rails\n\"25691697-fbd8-4278-8c38-b84068b7bc29\" = true\n\n# encode with ending in the middle\n\"384f0fea-1442-4f1a-a7c4-5cbc2044002c\" = true\n\n# decode with three rails\n\"cd525b17-ec34-45ef-8f0e-4f27c24a7127\" = true\n\n# decode with five rails\n\"dd7b4a98-1a52-4e5c-9499-cbb117833507\" = true\n\n# decode with six rails\n\"93e1ecf4-fac9-45d9-9cd2-591f47d3b8d3\" = true\n"
  },
  {
    "path": "exercises/practice/rail-fence-cipher/.meta/version",
    "content": "1.2.0"
  },
  {
    "path": "exercises/practice/rail-fence-cipher/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/rail-fence-cipher/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/rail-fence-cipher/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/rail-fence-cipher/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/rail-fence-cipher/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/rail-fence-cipher/src/main/kotlin/RailFenceCipher.kt",
    "content": "class RailFenceCipher {\n\n    // TODO: Implement proper constructor\n\n    fun getEncryptedData(input: String): String {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun getDecryptedData(input: String): String {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/rail-fence-cipher/src/test/kotlin/RailFenceCipherTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass RailFenceCipherTest {\n\n    @Test\n    fun encodeWithTwoRails() {\n        val railFenceCipher = RailFenceCipher(2)\n        assertEquals(\n                \"XXXXXXXXXOOOOOOOOO\",\n                railFenceCipher.getEncryptedData(\"XOXOXOXOXOXOXOXOXO\")\n        )\n    }\n\n    @Ignore\n    @Test\n    fun encodeWithThreeRails() {\n        val railFenceCipher = RailFenceCipher(3)\n        assertEquals(\n                \"WECRLTEERDSOEEFEAOCAIVDEN\",\n                railFenceCipher.getEncryptedData(\"WEAREDISCOVEREDFLEEATONCE\")\n        )\n    }\n\n    @Ignore\n    @Test\n    fun encodeWithEndingInTheMiddle() {\n        val railFenceCipher = RailFenceCipher(4)\n        assertEquals(\n                \"ESXIEECSR\",\n                railFenceCipher.getEncryptedData(\"EXERCISES\")\n        )\n    }\n\n    @Ignore\n    @Test\n    fun decodeWithThreeRails() {\n        val railFenceCipher = RailFenceCipher(3)\n        assertEquals(\n                \"THEDEVILISINTHEDETAILS\",\n                railFenceCipher.getDecryptedData(\"TEITELHDVLSNHDTISEIIEA\")\n        )\n    }\n\n    @Ignore\n    @Test\n    fun decodeWithFiveRails() {\n        val railFenceCipher = RailFenceCipher(5)\n        assertEquals(\n                \"EXERCISMISAWESOME\",\n                railFenceCipher.getDecryptedData(\"EIEXMSMESAORIWSCE\")\n        );\n    }\n\n    @Ignore\n    @Test\n    fun decodeWithSixRails() {\n        val railFenceCipher = RailFenceCipher(6)\n        assertEquals(\n                \"112358132134558914423337761098715972584418167651094617711286\",\n                railFenceCipher.getDecryptedData(\"133714114238148966225439541018335470986172518171757571896261\")\n        )\n    }\n}\n"
  },
  {
    "path": "exercises/practice/raindrops/.approaches/buildstring/content.md",
    "content": "# `buildString`\n\n```kotlin\nobject Raindrops {\n    fun convert(num: Int) = buildString {\n        if (num % 3 == 0) append(\"Pling\")\n        if (num % 5 == 0) append(\"Plang\")\n        if (num % 7 == 0) append(\"Plong\")\n        if (isEmpty()) append(num)\n    }\n}\n```\n\nAn [object declaration][object] is used to define `Raindrops` as essentially a [singleton][singleton] object instantiation of the class.\nThis is sufficient, since there is no object state that needs to change with each call of the `convert` method.\n\nThe `convert` function is implemented with a call to the [`buildString`][buildstring] function.\nAlthough the `convert` function has multiple lines, it consists only of the one `buildString` expression, so it is defined using\n[single-expression function][single-expression-function] syntax, with the curly braces omitted from the `convert` function call\nand the return type [inferred][type-inference].\n\nThe `builderAction` argument is a block of statements, each of which calls one or more methods on an implicit [`StringBuilder`][stringbuilder] object.\nThe [modulus operator][modulus-operator] (`%`) is used to check if the input number is evenly divisible by `3`, `5`, or `7`.\nIf so, then the [`append`][append] method is called on the`StringBuilder` to add the associated sound.\n\nAfter all of the numbers have been checked, the [`isEmpty`][isempty] method of `StringBuilder` is used to see if no sound was added.\nIf no sound was added, then the input number number is automatically converted to a `String` when appended to the `StringBuilder`.\n\nThe `convert` function returns the result of calling `buildString`, which is the result of the implicit call to the [`toString`][tostring]\nmethod of the `StringBuilder` after the block of statements in the `buildAction` argument.\n\n[object]: https://kotlinlang.org/docs/object-declarations.html#object-declarations-overview\n[singleton]: https://en.wikipedia.org/wiki/Singleton_pattern\n[single-expression-function]: https://kotlinlang.org/docs/functions.html#single-expression-functions\n[type-inference]: https://kotlinlang.org/spec/type-inference.html\n[modulus-operator]: https://www.programiz.com/kotlin-programming/operators\n[buildstring]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/build-string.html#buildstring\n[stringbuilder]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-string-builder/\n[append]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/append.html\n[isempty]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/is-empty.html\n[tostring]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-string-builder/to-string.html\n"
  },
  {
    "path": "exercises/practice/raindrops/.approaches/buildstring/snippet.txt",
    "content": "object Raindrops {\n    fun convert(num: Int) = buildString {\n        if (num % 3 == 0) append(\"Pling\")\n        if (num % 5 == 0) append(\"Plang\")\n        if (num % 7 == 0) append(\"Plong\")\n        if (isEmpty()) append(num)\n    }\n}\n"
  },
  {
    "path": "exercises/practice/raindrops/.approaches/config.json",
    "content": "{\n  \"introduction\": {\n    \"authors\": [\n      \"bobahop\"\n    ]\n  },\n  \"approaches\": [\n    {\n      \"uuid\": \"d0608dd0-9320-46c2-af9e-e54b9d0fc354\",\n      \"slug\": \"buildstring\",\n      \"title\": \"buildString\",\n      \"blurb\": \"Use buildString to return the result.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    },\n    {\n      \"uuid\": \"7d435fdf-db16-4c89-b56f-fe71a68c1d1b\",\n      \"slug\": \"fold-on-list\",\n      \"title\": \"fold on a List\",\n      \"blurb\": \"Iterate a List with fold to return the result.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "exercises/practice/raindrops/.approaches/fold-on-list/content.md",
    "content": "# `fold` on a `List`\n\n```kotlin\nobject Raindrops {\n    fun convert(n: Int) =\n            listOf(3 to \"Pling\", 5 to \"Plang\", 7 to \"Plong\")\n                    .fold(\"\") { output, pair ->\n                        output + if (n % pair.first == 0) pair.second else \"\"\n                    }\n                    .ifEmpty { n.toString() }\n}\n```\n\nAn [object declaration][object] is used to define `Raindrops` as essentially a [singleton][singleton] object instantiation of the class.\nThis is sufficient, since there is no object state that needs to change with each call of the `convert` method.\n\nThe `convert` function is implemented with a call to a chain of functions which returns a single value.\nAlthough the `convert` function has multiple lines, it consists only of the one expression resulting from the function chain,\nso it is defined using [single-expression function][single-expression-function] syntax,\nwith the curly braces omitted from the `convert` function call and the return type [inferred][type-inference].\n\nThe first function is the [`listOf`][listof] method to create a [`List`][list] of [`Pair`][pair] values,\nusing the [`to`][to] keyword to associate a number with its sound.\n\nThe [`fold`][fold] method is called on the `List`.\nIts accumulating value is initialized with an empty `String`.\nThe [lambda][lambda] of `fold` takes the accumulating `String` value  as well as the `Pair` of each `List` element being iterated.\n\nIf the input number is evenly divisible by the number in the current `Pair` being iterated, then the sound from the `Pair` is concatenated\nto the accumulating `String`, otherwise, an empty string is concatenated to it.\nThe accumulating `String` is returned to the next iteration of `fold`.\n\nWhen `fold` has iterated through all of the `List` elements, the `StringBuilder` is the result.\nThe `convert` function returns the result of calling the [`ifEmpty`][ifempty] method on the `StringBuilder`.\nIf the `StringBuilder` content is empty, then it outputs the input number converterd to a `String`.\nOtherwise, it returns the content of the `StringBuilder` as a `String`.\n\n[object]: https://kotlinlang.org/docs/object-declarations.html#object-declarations-overview\n[singleton]: https://en.wikipedia.org/wiki/Singleton_pattern\n[single-expression-function]: https://kotlinlang.org/docs/functions.html#single-expression-functions\n[type-inference]: https://kotlinlang.org/spec/type-inference.html\n[listof]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/list-of.html\n[fold]: https://kotlinlang.org/docs/collection-aggregate.html#fold-and-reduce\n[list]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/\n[pair]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-pair/\n[to]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/to.html\n[lambda]: https://kotlinlang.org/docs/lambdas.html#lambda-expressions-and-anonymous-functions\n[ifempty]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/if-empty.html\n"
  },
  {
    "path": "exercises/practice/raindrops/.approaches/fold-on-list/snippet.txt",
    "content": "object Raindrops {\n    fun convert(n: Int) =\n            listOf(3 to \"Pling\", 5 to \"Plang\", 7 to \"Plong\")\n                    .fold(\"\") { output, pair ->\n                        output + if (n % pair.first == 0) pair.second else \"\"\n                    }\n                    .ifEmpty { n.toString() }\n}\n"
  },
  {
    "path": "exercises/practice/raindrops/.approaches/introduction.md",
    "content": "# Introduction\n\nThere are several idiomatic ways to solve Raindrops.\nOne way is to use the [`buildString`][buildstring] function.\nAnother way is to use the [`fold`][fold] method on a [`List`][list].\n\n## General guidance\n\nThe key to solving Raindrops is to know if the input is evenly divisible by `3`, `5` and/or `7`.\nFor determining that, you will use the [modulus operator][modulus-operator].\n\n## Approach: `buildString`\n\n```kotlin\nobject Raindrops {\n    fun convert(num: Int) = buildString {\n        if (num % 3 == 0) append(\"Pling\")\n        if (num % 5 == 0) append(\"Plang\")\n        if (num % 7 == 0) append(\"Plong\")\n        if (isEmpty()) append(num)\n    }\n}\n```\n\nFor more information, check the [`buildString` approach][approach-buildstring].\n\n\n## Approach: `fold` on a `List`\n\n```kotlin\nobject Raindrops {\n    fun convert(n: Int) =\n            listOf(3 to \"Pling\", 5 to \"Plang\", 7 to \"Plong\")\n                    .fold(\"\") { output, pair ->\n                        output + if (n % pair.first == 0) pair.second else \"\"\n                    }\n                    .ifEmpty { n.toString() }\n}\n```\n\nFor more information, check the [`fold` on a `List` approach][approach-fold-on-list].\n\n## Which approach to use?\n\nBenchmarking is currently outside the scope of this document,\nso which to use is a matter of stylistic choice.\nAn advantage for `List` is that, if another type of raindrop were to be added, only another entry would be added to the `List`,\nand no other code would need to be added.\n\n[approach-buildstring]: https://exercism.org/tracks/kotlin/exercises/raindrops/approaches/buildstring\n[approach-fold-on-list]: https://exercism.org/tracks/kotlin/exercises/raindrops/approaches/fold-on-list\n[modulus-operator]: https://www.programiz.com/kotlin-programming/operators\n[buildstring]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/build-string.html#buildstring\n[fold]: https://kotlinlang.org/docs/collection-aggregate.html#fold-and-reduce\n[list]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/\n"
  },
  {
    "path": "exercises/practice/raindrops/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to convert a number into its corresponding raindrop sounds.\n\nIf a given number:\n\n- is divisible by 3, add \"Pling\" to the result.\n- is divisible by 5, add \"Plang\" to the result.\n- is divisible by 7, add \"Plong\" to the result.\n- **is not** divisible by 3, 5, or 7, the result should be the number as a string.\n\n## Examples\n\n- 28 is divisible by 7, but not 3 or 5, so the result would be `\"Plong\"`.\n- 30 is divisible by 3 and 5, but not 7, so the result would be `\"PlingPlang\"`.\n- 34 is not divisible by 3, 5, or 7, so the result would be `\"34\"`.\n\n~~~~exercism/note\nA common way to test if one number is evenly divisible by another is to compare the [remainder][remainder] or [modulus][modulo] to zero.\nMost languages provide operators or functions for one (or both) of these.\n\n[remainder]: https://exercism.org/docs/programming/operators/remainder\n[modulo]: https://en.wikipedia.org/wiki/Modulo_operation\n~~~~\n"
  },
  {
    "path": "exercises/practice/raindrops/.docs/introduction.md",
    "content": "# Introduction\n\nRaindrops is a slightly more complex version of the FizzBuzz challenge, a classic interview question.\n"
  },
  {
    "path": "exercises/practice/raindrops/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Raindrops.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/RaindropsTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Raindrops.kt\"\n    ]\n  },\n  \"blurb\": \"Convert a number into its corresponding raindrop sounds - Pling, Plang and Plong.\",\n  \"source\": \"A variation on FizzBuzz, a famous technical interview question that is intended to weed out potential candidates. That question is itself derived from Fizz Buzz, a popular children's game for teaching division.\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Fizz_buzz\"\n}\n"
  },
  {
    "path": "exercises/practice/raindrops/.meta/src/reference/kotlin/Raindrops.kt",
    "content": "object Raindrops {\n    private val sounds = listOf(Pair(3, \"Pling\"), Pair(5, \"Plang\"), Pair(7, \"Plong\"))\n\n    fun convert(n: Int): String {\n        val result = sounds.filter { n % it.first == 0 }.joinToString(\"\") { it.second }\n\n        return result.ifEmpty { n.toString() }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/raindrops/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# the sound for 1 is 1\n\"1575d549-e502-46d4-a8e1-6b7bec6123d8\" = true\n\n# the sound for 3 is Pling\n\"1f51a9f9-4895-4539-b182-d7b0a5ab2913\" = true\n\n# the sound for 5 is Plang\n\"2d9bfae5-2b21-4bcd-9629-c8c0e388f3e0\" = true\n\n# the sound for 7 is Plong\n\"d7e60daa-32ef-4c23-b688-2abff46c4806\" = true\n\n# the sound for 6 is Pling as it has a factor 3\n\"6bb4947b-a724-430c-923f-f0dc3d62e56a\" = true\n\n# 2 to the power 3 does not make a raindrop sound as 3 is the exponent not the base\n\"ce51e0e8-d9d4-446d-9949-96eac4458c2d\" = true\n\n# the sound for 9 is Pling as it has a factor 3\n\"0dd66175-e3e2-47fc-8750-d01739856671\" = true\n\n# the sound for 10 is Plang as it has a factor 5\n\"022c44d3-2182-4471-95d7-c575af225c96\" = true\n\n# the sound for 14 is Plong as it has a factor of 7\n\"37ab74db-fed3-40ff-b7b9-04acdfea8edf\" = true\n\n# the sound for 15 is PlingPlang as it has factors 3 and 5\n\"31f92999-6afb-40ee-9aa4-6d15e3334d0f\" = true\n\n# the sound for 21 is PlingPlong as it has factors 3 and 7\n\"ff9bb95d-6361-4602-be2c-653fe5239b54\" = true\n\n# the sound for 25 is Plang as it has a factor 5\n\"d2e75317-b72e-40ab-8a64-6734a21dece1\" = true\n\n# the sound for 27 is Pling as it has a factor 3\n\"a09c4c58-c662-4e32-97fe-f1501ef7125c\" = true\n\n# the sound for 35 is PlangPlong as it has factors 5 and 7\n\"bdf061de-8564-4899-a843-14b48b722789\" = true\n\n# the sound for 49 is Plong as it has a factor 7\n\"c4680bee-69ba-439d-99b5-70c5fd1a7a83\" = true\n\n# the sound for 52 is 52\n\"17f2bc9a-b65a-4d23-8ccd-266e8c271444\" = true\n\n# the sound for 105 is PlingPlangPlong as it has factors 3, 5 and 7\n\"e46677ed-ff1a-419f-a740-5c713d2830e4\" = true\n\n# the sound for 3125 is Plang as it has a factor 5\n\"13c6837a-0fcd-4b86-a0eb-20572f7deb0b\" = true\n"
  },
  {
    "path": "exercises/practice/raindrops/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/raindrops/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/raindrops/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/raindrops/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/raindrops/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/raindrops/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/raindrops/src/main/kotlin/Raindrops.kt",
    "content": "object Raindrops {\n\n    fun convert(n: Int): String {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/raindrops/src/test/kotlin/RaindropsTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport org.junit.runner.RunWith\nimport org.junit.runners.Parameterized\nimport kotlin.test.assertEquals\n\n@RunWith(Parameterized::class)\nclass RaindropsTest(val input: Int, val expectedOutput: String) {\n\n    companion object {\n        @JvmStatic\n        @Parameterized.Parameters(name = \"{index}: raindrops({0})={1}\")\n        fun data() = listOf(\n                arrayOf(   1, \"1\"),\n                arrayOf(   3, \"Pling\"),\n                arrayOf(   5, \"Plang\"),\n                arrayOf(   7, \"Plong\"),\n                arrayOf(   6, \"Pling\"),\n                arrayOf(   8, \"8\"),\n                arrayOf(   9, \"Pling\"),\n                arrayOf(  10, \"Plang\"),\n                arrayOf(  14, \"Plong\"),\n                arrayOf(  15, \"PlingPlang\"),\n                arrayOf(  21, \"PlingPlong\"),\n                arrayOf(  25, \"Plang\"),\n                arrayOf(  27, \"Pling\"),\n                arrayOf(  35, \"PlangPlong\"),\n                arrayOf(  49, \"Plong\"),\n                arrayOf(  52, \"52\"),\n                arrayOf( 105, \"PlingPlangPlong\"),\n                arrayOf(3125, \"Plang\")\n        )\n    }\n\n    @Test\n    fun test() {\n        assertEquals(expectedOutput, Raindrops.convert(input))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/react/.docs/instructions.md",
    "content": "# Instructions\n\nImplement a basic reactive system.\n\nReactive programming is a programming paradigm that focuses on how values are computed in terms of each other to allow a change to one value to automatically propagate to other values, like in a spreadsheet.\n\nImplement a basic reactive system with cells with settable values (\"input\" cells) and cells with values computed in terms of other cells (\"compute\" cells).\nImplement updates so that when an input value is changed, values propagate to reach a new stable system state.\n\nIn addition, compute cells should allow for registering change notification callbacks.\nCall a cell’s callbacks when the cell’s value in a new stable state has changed from the previous stable state.\n"
  },
  {
    "path": "exercises/practice/react/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"petertseng\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/React.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ReactTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/React.kt\"\n    ]\n  },\n  \"blurb\": \"Implement a basic reactive system.\"\n}\n"
  },
  {
    "path": "exercises/practice/react/.meta/src/reference/kotlin/React.kt",
    "content": "class Reactor<T>() {\n    abstract inner class Cell {\n        abstract val value: T\n        internal val dependents = mutableListOf<ComputeCell>()\n    }\n\n    interface Subscription {\n        fun cancel()\n    }\n\n    inner class InputCell(initialValue: T) : Cell() {\n        override var value: T = initialValue\n            set(newValue) {\n                field = newValue\n                dependents.forEach { it.propagate() }\n                dependents.forEach { it.fireCallbacks() }\n            }\n    }\n\n    inner class ComputeCell private constructor(val newValue: () -> T) : Cell() {\n        override var value: T = newValue()\n            private set\n\n        private var lastCallbackValue = value\n        private var callbacksIssued = 0\n        private val activeCallbacks = mutableMapOf<Int, (T) -> Any>()\n\n        constructor(vararg cells: Cell, f: (List<T>) -> T) : this({ f(cells.map { it.value }) }) {\n            for (cell in cells) {\n                cell.dependents.add(this)\n            }\n        }\n\n        fun addCallback(f: (T) -> Any): Subscription {\n            val id = callbacksIssued\n            callbacksIssued++\n            activeCallbacks[id] = f\n            return object : Subscription {\n                override fun cancel() {\n                    activeCallbacks.remove(id)\n                }\n            }\n        }\n\n        internal fun propagate() {\n            val nv = newValue()\n            if (nv == value) {\n                return\n            }\n            value = nv\n            dependents.forEach { it.propagate() }\n        }\n\n        internal fun fireCallbacks() {\n            if (value == lastCallbackValue) {\n                return\n            }\n            lastCallbackValue = value\n            for (cb in activeCallbacks.values) {\n                cb(value)\n            }\n            dependents.forEach { it.fireCallbacks() }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/react/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# input cells have a value\n\"c51ee736-d001-4f30-88d1-0c8e8b43cd07\" = true\n\n# an input cell's value can be set\n\"dedf0fe0-da0c-4d5d-a582-ffaf5f4d0851\" = true\n\n# compute cells calculate initial value\n\"5854b975-f545-4f93-8968-cc324cde746e\" = true\n\n# compute cells take inputs in the right order\n\"25795a3d-b86c-4e91-abe7-1c340e71560c\" = true\n\n# compute cells update value when dependencies are changed\n\"c62689bf-7be5-41bb-b9f8-65178ef3e8ba\" = true\n\n# compute cells can depend on other compute cells\n\"5ff36b09-0a88-48d4-b7f8-69dcf3feea40\" = true\n\n# compute cells fire callbacks\n\"abe33eaf-68ad-42a5-b728-05519ca88d2d\" = true\n\n# callback cells only fire on change\n\"9e5cb3a4-78e5-4290-80f8-a78612c52db2\" = true\n\n# callbacks do not report already reported values\n\"ada17cb6-7332-448a-b934-e3d7495c13d3\" = true\n\n# callbacks can fire from multiple cells\n\"ac271900-ea5c-461c-9add-eeebcb8c03e5\" = true\n\n# callbacks can be added and removed\n\"95a82dcc-8280-4de3-a4cd-4f19a84e3d6f\" = true\n\n# removing a callback multiple times doesn't interfere with other callbacks\n\"f2a7b445-f783-4e0e-8393-469ab4915f2a\" = true\n\n# callbacks should only be called once even if multiple dependencies change\n\"daf6feca-09e0-4ce5-801d-770ddfe1c268\" = true\n\n# callbacks should not be called if dependencies change but output value doesn't change\n\"9a5b159f-b7aa-4729-807e-f1c38a46d377\" = true\n"
  },
  {
    "path": "exercises/practice/react/.meta/version",
    "content": "1.0.0\n"
  },
  {
    "path": "exercises/practice/react/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/react/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/react/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/react/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/react/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/react/src/main/kotlin/React.kt",
    "content": "class Reactor<T>() {\n    // Your compute cell's addCallback method must return an object\n    // that implements the Subscription interface.\n    interface Subscription {\n        fun cancel()\n    }\n}\n"
  },
  {
    "path": "exercises/practice/react/src/test/kotlin/ReactTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport org.junit.runner.RunWith\nimport org.junit.runners.Parameterized\nimport kotlin.test.assertEquals\n\nclass ReactTest {\n\n    @Test\n    fun inputCellsHaveValue() {\n        val reactor = Reactor<Int>()\n        val input = reactor.InputCell(10)\n        assertEquals(10, input.value)\n    }\n\n    @Ignore\n    @Test\n    fun inputCellsValueCanBeSet() {\n        val reactor = Reactor<Int>()\n        val input = reactor.InputCell(4)\n        input.value = 20\n        assertEquals(20, input.value)\n    }\n\n    @Ignore\n    @Test\n    fun computeCellsCalculateInitialValue() {\n        val reactor = Reactor<Int>()\n        val input = reactor.InputCell(1)\n        val output = reactor.ComputeCell(input) { it[0] + 1 }\n        assertEquals(2, output.value)\n    }\n\n    @Ignore\n    @Test\n    fun computeCellsTakeInputsInTheRightOrder() {\n        val reactor = Reactor<Int>()\n        val one = reactor.InputCell(1)\n        val two = reactor.InputCell(2)\n        val output = reactor.ComputeCell(one, two) { (x, y) -> x + y * 10 }\n        assertEquals(21, output.value)\n    }\n\n    @Ignore\n    @Test\n    fun computeCellsUpdateValueWhenDependenciesAreChanged() {\n        val reactor = Reactor<Int>()\n        val input = reactor.InputCell(1)\n        val output = reactor.ComputeCell(input) { it[0] + 1 }\n        input.value = 3\n        assertEquals(4, output.value)\n    }\n\n    @Ignore\n    @Test\n    fun computeCellsCanDependOnOtherComputeCells() {\n        val reactor = Reactor<Int>()\n        val input = reactor.InputCell(1)\n        val timesTwo = reactor.ComputeCell(input) { it[0] * 2 }\n        val timesThirty = reactor.ComputeCell(input) { it[0] * 30 }\n        val output = reactor.ComputeCell(timesTwo, timesThirty) { (x, y) -> x + y }\n\n        assertEquals(32, output.value)\n        input.value = 3\n        assertEquals(96, output.value)\n    }\n\n    @Ignore\n    @Test\n    fun computeCellsFireCallbacks() {\n        val reactor = Reactor<Int>()\n        val input = reactor.InputCell(1)\n        val output = reactor.ComputeCell(input) { it[0] + 1 }\n\n        val vals = mutableListOf<Int>()\n        output.addCallback { vals.add(it) }\n\n        input.value = 3\n        assertEquals(listOf(4), vals)\n    }\n\n    @Ignore\n    @Test\n    fun callbacksOnlyFireOnChange() {\n        val reactor = Reactor<Int>()\n        val input = reactor.InputCell(1)\n        val output = reactor.ComputeCell(input) { if (it[0] < 3) 111 else 222 }\n\n        val vals = mutableListOf<Int>()\n        output.addCallback { vals.add(it) }\n\n        input.value = 2\n        assertEquals(listOf<Int>(), vals)\n\n        input.value = 4\n        assertEquals(listOf(222), vals)\n    }\n\n    @Ignore\n    @Test\n    fun callbacksCanBeAddedAndRemoved() {\n        val reactor = Reactor<Int>()\n        val input = reactor.InputCell(11)\n        val output = reactor.ComputeCell(input) { it[0] + 1 }\n\n        val vals1 = mutableListOf<Int>()\n        val sub1 = output.addCallback { vals1.add(it) }\n        val vals2 = mutableListOf<Int>()\n        output.addCallback { vals2.add(it) }\n\n        input.value = 31\n        sub1.cancel()\n\n        val vals3 = mutableListOf<Int>()\n        output.addCallback { vals3.add(it) }\n\n        input.value = 41\n\n        assertEquals(listOf(32), vals1)\n        assertEquals(listOf(32, 42), vals2)\n        assertEquals(listOf(42), vals3)\n    }\n\n    @Ignore\n    @Test\n    fun removingACallbackMultipleTimesDoesntInterfereWithOtherCallbacks() {\n        val reactor = Reactor<Int>()\n        val input = reactor.InputCell(1)\n        val output = reactor.ComputeCell(input) { it[0] + 1 }\n\n        val vals1 = mutableListOf<Int>()\n        val sub1 = output.addCallback { vals1.add(it) }\n        val vals2 = mutableListOf<Int>()\n        output.addCallback { vals2.add(it) }\n\n        for (i in 1..3) {\n            sub1.cancel()\n        }\n\n        input.value = 2\n        assertEquals(listOf<Int>(), vals1)\n        assertEquals(listOf(3), vals2)\n    }\n\n    @Ignore\n    @Test\n    fun callbacksShouldOnlyBeCalledOnceEvenIfMultipleDependenciesChange() {\n        val reactor = Reactor<Int>()\n        val input = reactor.InputCell(1)\n        val plusOne = reactor.ComputeCell(input) { it[0] + 1 }\n        val minusOne1 = reactor.ComputeCell(input) { it[0] - 1 }\n        val minusOne2 = reactor.ComputeCell(minusOne1) { it[0] - 1 }\n        val output = reactor.ComputeCell(plusOne, minusOne2) { (x, y) -> x * y }\n\n        val vals = mutableListOf<Int>()\n        output.addCallback { vals.add(it) }\n\n        input.value = 4\n        assertEquals(listOf(10), vals)\n    }\n\n    @Ignore\n    @Test\n    fun callbacksShouldNotBeCalledIfDependenciesChangeButOutputValueDoesntChange() {\n        val reactor = Reactor<Int>()\n        val input = reactor.InputCell(1)\n        val plusOne = reactor.ComputeCell(input) { it[0] + 1 }\n        val minusOne = reactor.ComputeCell(input) { it[0] - 1 }\n        val alwaysTwo = reactor.ComputeCell(plusOne, minusOne) { (x, y) -> x - y }\n\n        val vals = mutableListOf<Int>()\n        alwaysTwo.addCallback { vals.add(it) }\n\n        for (i in 2..5) {\n            input.value = i\n        }\n\n        assertEquals(listOf<Int>(), vals)\n    }\n\n}\n\n/*\n * Extension\n *\n * This is a digital logic circuit called an adder:\n * https://en.wikipedia.org/wiki/Adder_(electronics)\n */\n@RunWith(Parameterized::class)\nclass ReactAdderTest(val input: Input, val expected: Expected) {\n\n    companion object {\n        data class Input(val a: Boolean, val b: Boolean, val carryIn: Boolean)\n        data class Expected(val carryOut: Boolean, val sum: Boolean)\n\n        @JvmStatic\n        @Parameterized.Parameters(name = \"{index}: {0} = {1}\")\n        fun data() = listOf(\n                arrayOf(Input(a=false, b=false, carryIn=false), Expected(carryOut=false, sum=false)),\n                arrayOf(Input(a=false, b=false, carryIn=true),  Expected(carryOut=false, sum=true)),\n                arrayOf(Input(a=false, b=true,  carryIn=false), Expected(carryOut=false, sum=true)),\n                arrayOf(Input(a=false, b=true,  carryIn=true),  Expected(carryOut=true,  sum=false)),\n                arrayOf(Input(a=true,  b=false, carryIn=false), Expected(carryOut=false, sum=true)),\n                arrayOf(Input(a=true,  b=false, carryIn=true),  Expected(carryOut=true,  sum=false)),\n                arrayOf(Input(a=true,  b=true,  carryIn=false), Expected(carryOut=true,  sum=false)),\n                arrayOf(Input(a=true,  b=true,  carryIn=true),  Expected(carryOut=true,  sum=true))\n        )\n    }\n\n    @Ignore\n    @Test\n    fun test() {\n        val reactor = Reactor<Boolean>()\n        val a = reactor.InputCell(input.a)\n        val b = reactor.InputCell(input.b)\n        val carryIn = reactor.InputCell(input.carryIn)\n\n        val aXorB = reactor.ComputeCell(a, b) { (x, y) -> x.xor(y) }\n        val sum = reactor.ComputeCell(aXorB, carryIn) { (x, y) -> x.xor(y) }\n\n        val aXorBAndCin = reactor.ComputeCell(aXorB, carryIn) { (x, y) -> x && y }\n        val aAndB = reactor.ComputeCell(a, b) { (x, y) -> x && y }\n        val carryOut = reactor.ComputeCell(aXorBAndCin, aAndB) { (x, y) -> x || y }\n\n        assertEquals(expected, Expected(sum=sum.value, carryOut=carryOut.value))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color/.docs/instructions.md",
    "content": "# Instructions\n\nIf you want to build something using a Raspberry Pi, you'll probably use _resistors_.\nFor this exercise, you need to know two things about them:\n\n- Each resistor has a resistance value.\n- Resistors are small - so small in fact that if you printed the resistance value on them, it would be hard to read.\n\nTo get around this problem, manufacturers print color-coded bands onto the resistors to denote their resistance values.\nEach band has a position and a numeric value.\n\nThe first 2 bands of a resistor have a simple encoding scheme: each color maps to a single number.\n\nIn this exercise you are going to create a helpful program so that you don't have to remember the values of the bands.\n\nThese colors are encoded as follows:\n\n- black: 0\n- brown: 1\n- red: 2\n- orange: 3\n- yellow: 4\n- green: 5\n- blue: 6\n- violet: 7\n- grey: 8\n- white: 9\n\nThe goal of this exercise is to create a way:\n\n- to look up the numerical value associated with a particular color band\n- to list the different band colors\n\nMnemonics map the colors to the numbers, that, when stored as an array, happen to map to their index in the array:\nBetter Be Right Or Your Great Big Values Go Wrong.\n\nMore information on the color encoding of resistors can be found in the [Electronic color code Wikipedia article][e-color-code].\n\n[e-color-code]: https://en.wikipedia.org/wiki/Electronic_color_code\n"
  },
  {
    "path": "exercises/practice/resistor-color/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/ResistorColor.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ResistorColorTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/ResistorColor.kt\"\n    ]\n  },\n  \"blurb\": \"Convert a resistor band's color to its numeric representation.\",\n  \"source\": \"Maud de Vries, Erik Schierboom\",\n  \"source_url\": \"https://github.com/exercism/problem-specifications/issues/1458\"\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color/.meta/src/reference/kotlin/ResistorColor.kt",
    "content": "object ResistorColor {\n\n    private val colors = listOf(\"black\", \"brown\", \"red\", \"orange\", \"yellow\", \"green\", \"blue\", \"violet\", \"grey\", \"white\")\n\n    fun colorCode(input: String): Int = colors.indexOf(input)\n\n    fun colors() = colors\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# Black\n\"49eb31c5-10a8-4180-9f7f-fea632ab87ef\" = true\n\n# White\n\"0a4df94b-92da-4579-a907-65040ce0b3fc\" = true\n\n# Orange\n\"5f81608d-f36f-4190-8084-f45116b6f380\" = true\n\n# Colors\n\"581d68fa-f968-4be2-9f9d-880f2fb73cf7\" = true\n"
  },
  {
    "path": "exercises/practice/resistor-color/.meta/version",
    "content": "1.0.0\n"
  },
  {
    "path": "exercises/practice/resistor-color/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/resistor-color/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/resistor-color/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/resistor-color/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color/src/main/kotlin/ResistorColor.kt",
    "content": "object ResistorColor {\n\n    fun colorCode(input: String): Int {\n        TODO(\"Implement this to complete the task\")\n    }\n\n    fun colors(): List<String> {\n        TODO(\"Implement this to complete the task\")\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color/src/test/kotlin/ResistorColorTest.kt",
    "content": "import kotlin.test.Ignore\nimport kotlin.test.assertEquals\nimport kotlin.test.Test\n\nclass ResistorColorTest {\n\n    @Test\n    fun testBlackColorCode() = assertEquals(0, ResistorColor.colorCode(\"black\"))\n\n    @Ignore\n    @Test\n    fun testWhiteColorCode() = assertEquals(9, ResistorColor.colorCode(\"white\"))\n\n    @Ignore\n    @Test\n    fun testOrangeColorCode() = assertEquals(3, ResistorColor.colorCode(\"orange\"))\n\n    @Ignore\n    @Test\n    fun testColors() {\n        val expected = listOf(\"black\", \"brown\", \"red\", \"orange\", \"yellow\", \"green\", \"blue\", \"violet\", \"grey\", \"white\")\n        assertEquals(expected, ResistorColor.colors())\n    }\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-duo/.docs/instructions.md",
    "content": "# Instructions\n\nIf you want to build something using a Raspberry Pi, you'll probably use _resistors_.\nFor this exercise, you need to know two things about them:\n\n- Each resistor has a resistance value.\n- Resistors are small - so small in fact that if you printed the resistance value on them, it would be hard to read.\n\nTo get around this problem, manufacturers print color-coded bands onto the resistors to denote their resistance values.\nEach band has a position and a numeric value.\n\nThe first 2 bands of a resistor have a simple encoding scheme: each color maps to a single number.\nFor example, if they printed a brown band (value 1) followed by a green band (value 5), it would translate to the number 15.\n\nIn this exercise you are going to create a helpful program so that you don't have to remember the values of the bands.\nThe program will take color names as input and output a two digit number, even if the input is more than two colors!\n\nThe band colors are encoded as follows:\n\n- black: 0\n- brown: 1\n- red: 2\n- orange: 3\n- yellow: 4\n- green: 5\n- blue: 6\n- violet: 7\n- grey: 8\n- white: 9\n\nFrom the example above:\nbrown-green should return 15, and\nbrown-green-violet should return 15 too, ignoring the third color.\n"
  },
  {
    "path": "exercises/practice/resistor-color-duo/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/ResistorColorDuo.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ResistorColorDuoTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/ResistorColorDuo.kt\"\n    ]\n  },\n  \"blurb\": \"Convert color codes, as used on resistors, to a numeric value.\",\n  \"source\": \"Maud de Vries, Erik Schierboom\",\n  \"source_url\": \"https://github.com/exercism/problem-specifications/issues/1464\"\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-duo/.meta/src/reference/kotlin/Color.kt",
    "content": "enum class Color {\n    BLACK, BROWN, RED, ORANGE, YELLOW, GREEN, BLUE, VIOLET, GREY, WHITE\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-duo/.meta/src/reference/kotlin/ResistorColorDuo.kt",
    "content": "object ResistorColorDuo {\n    fun value(vararg colors: Color): Int = 10 * colors[0].ordinal + colors[1].ordinal\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-duo/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# Brown and black\n\"ce11995a-5b93-4950-a5e9-93423693b2fc\" = true\n\n# Blue and grey\n\"7bf82f7a-af23-48ba-a97d-38d59406a920\" = true\n\n# Yellow and violet\n\"f1886361-fdfd-4693-acf8-46726fe24e0c\" = true\n\n# Orange and orange\n\"77a8293d-2a83-4016-b1af-991acc12b9fe\" = true\n\n# Ignore additional colors\n\"0c4fb44f-db7c-4d03-afa8-054350f156a8\" = true\n"
  },
  {
    "path": "exercises/practice/resistor-color-duo/.meta/version",
    "content": "2.1.0\n"
  },
  {
    "path": "exercises/practice/resistor-color-duo/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-duo/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/resistor-color-duo/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/resistor-color-duo/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/resistor-color-duo/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-duo/src/main/kotlin/Color.kt",
    "content": "enum class Color {\n    BLACK, BROWN, RED, ORANGE, YELLOW, GREEN, BLUE, VIOLET, GREY, WHITE\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-duo/src/main/kotlin/ResistorColorDuo.kt",
    "content": "object ResistorColorDuo {\n\n    fun value(vararg colors: Color): Int {\n        TODO(\"Implement this to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-duo/src/test/kotlin/ResistorColorDuoTest.kt",
    "content": "import kotlin.test.Ignore\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\n\nclass ResistorColorDuoTest {\n\n    @Test\n    fun `brown and black`() = assertEquals(10, ResistorColorDuo.value(Color.BROWN, Color.BLACK))\n\n    @Ignore\n    @Test\n    fun `blue and grey`() = assertEquals(68, ResistorColorDuo.value(Color.BLUE, Color.GREY))\n\n    @Ignore\n    @Test\n    fun `yellow and violet`() = assertEquals(47, ResistorColorDuo.value(Color.YELLOW, Color.VIOLET))\n\n    @Ignore\n    @Test\n    fun `orange and orange`() = assertEquals(33, ResistorColorDuo.value(Color.ORANGE, Color.ORANGE))\n\n    @Ignore\n    @Test\n    fun `ignore additional colors`() = assertEquals(51, ResistorColorDuo.value(Color.GREEN, Color.BROWN, Color.ORANGE))\n\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/.docs/instructions.md",
    "content": "# Instructions\n\nIf you want to build something using a Raspberry Pi, you'll probably use _resistors_.\nFor this exercise, you need to know only three things about them:\n\n- Each resistor has a resistance value.\n- Resistors are small - so small in fact that if you printed the resistance value on them, it would be hard to read.\n  To get around this problem, manufacturers print color-coded bands onto the resistors to denote their resistance values.\n- Each band acts as a digit of a number.\n  For example, if they printed a brown band (value 1) followed by a green band (value 5), it would translate to the number 15.\n  In this exercise, you are going to create a helpful program so that you don't have to remember the values of the bands.\n  The program will take 3 colors as input, and outputs the correct value, in ohms.\n  The color bands are encoded as follows:\n\n- black: 0\n- brown: 1\n- red: 2\n- orange: 3\n- yellow: 4\n- green: 5\n- blue: 6\n- violet: 7\n- grey: 8\n- white: 9\n\nIn Resistor Color Duo you decoded the first two colors.\nFor instance: orange-orange got the main value `33`.\nThe third color stands for how many zeros need to be added to the main value.\nThe main value plus the zeros gives us a value in ohms.\nFor the exercise it doesn't matter what ohms really are.\nFor example:\n\n- orange-orange-black would be 33 and no zeros, which becomes 33 ohms.\n- orange-orange-red would be 33 and 2 zeros, which becomes 3300 ohms.\n- orange-orange-orange would be 33 and 3 zeros, which becomes 33000 ohms.\n\n(If Math is your thing, you may want to think of the zeros as exponents of 10.\nIf Math is not your thing, go with the zeros.\nIt really is the same thing, just in plain English instead of Math lingo.)\n\nThis exercise is about translating the colors into a label:\n\n> \"... ohms\"\n\nSo an input of `\"orange\", \"orange\", \"black\"` should return:\n\n> \"33 ohms\"\n\nWhen we get to larger resistors, a [metric prefix][metric-prefix] is used to indicate a larger magnitude of ohms, such as \"kiloohms\".\nThat is similar to saying \"2 kilometers\" instead of \"2000 meters\", or \"2 kilograms\" for \"2000 grams\".\n\nFor example, an input of `\"orange\", \"orange\", \"orange\"` should return:\n\n> \"33 kiloohms\"\n\n[metric-prefix]: https://en.wikipedia.org/wiki/Metric_prefix\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/ResistorColorTrio.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ResistorColorTrioTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/ResistorColorTrio.kt\"\n    ]\n  },\n  \"blurb\": \"Convert color codes, as used on resistors, to a human-readable label.\",\n  \"source\": \"Maud de Vries, Erik Schierboom\",\n  \"source_url\": \"https://github.com/exercism/problem-specifications/issues/1549\"\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/.meta/src/reference/kotlin/Color.kt",
    "content": "enum class Color {\n    BLACK, BROWN, RED, ORANGE, YELLOW, GREEN, BLUE, VIOLET, GREY, WHITE\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/.meta/src/reference/kotlin/ResistorColorTrio.kt",
    "content": "import kotlin.math.log10\nimport kotlin.math.pow\n\nobject ResistorColorTrio {\n\n    fun text(vararg input: Color): String {\n        val duoValue = 10 * input[0].ordinal + input[1].ordinal\n        val trioValue = duoValue * 10.0.pow(input[2].ordinal)\n\n        val thousandPowers = (log10(trioValue) / 3).toInt()\n        val resultValue = (trioValue / 1000.0.pow(thousandPowers)).toInt()\n        val resultUnit = Unit.values()[thousandPowers].name.lowercase()\n\n        return \"$resultValue $resultUnit\"\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/.meta/src/reference/kotlin/Unit.kt",
    "content": "enum class Unit {\n    OHMS, KILOOHMS, MEGAOHMS, GIGAOHMS, TERAOHMS, PETAOHMS, EXAOHMS\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# Orange and orange and black\n\"d6863355-15b7-40bb-abe0-bfb1a25512ed\" = true\n\n# Blue and grey and brown\n\"1224a3a9-8c8e-4032-843a-5224e04647d6\" = true\n\n# Red and black and red\n\"b8bda7dc-6b95-4539-abb2-2ad51d66a207\" = true\n\n# Green and brown and orange\n\"5b1e74bc-d838-4eda-bbb3-eaba988e733b\" = true\n\n# Yellow and violet and yellow\n\"f5d37ef9-1919-4719-a90d-a33c5a6934c9\" = true\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/.meta/version",
    "content": "1.0.0\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/src/main/kotlin/Color.kt",
    "content": "enum class Color {\n    BLACK, BROWN, RED, ORANGE, YELLOW, GREEN, BLUE, VIOLET, GREY, WHITE\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/src/main/kotlin/ResistorColorTrio.kt",
    "content": "object ResistorColorTrio {\n\n    fun text(vararg input: Color): String {\n        TODO(\"Implement this to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/src/main/kotlin/Unit.kt",
    "content": "enum class Unit {\n    OHMS, KILOOHMS, MEGAOHMS, GIGAOHMS, TERAOHMS, PETAOHMS, EXAOHMS\n}\n"
  },
  {
    "path": "exercises/practice/resistor-color-trio/src/test/kotlin/ResistorColorTrioTest.kt",
    "content": "import kotlin.test.Test\nimport kotlin.test.assertEquals\nimport Color.*\nimport kotlin.test.Ignore\n\nclass ResistorColorTrioTest {\n\n    @Test\n    fun `orange orange black`() = assertEquals(\"33 ohms\", ResistorColorTrio.text(ORANGE, ORANGE, BLACK))\n\n    @Ignore\n    @Test\n    fun `blue grey brown`() = assertEquals(\"680 ohms\", ResistorColorTrio.text(BLUE, GREY, BROWN))\n\n    @Ignore\n    @Test\n    fun `red black red`() = assertEquals(\"2 kiloohms\", ResistorColorTrio.text(RED, BLACK, RED))\n\n    @Ignore\n    @Test\n    fun `green brown orange`() = assertEquals(\"51 kiloohms\", ResistorColorTrio.text(GREEN, BROWN, ORANGE))\n\n    @Ignore\n    @Test\n    fun `yellow violet yellow`() = assertEquals(\"470 kiloohms\", ResistorColorTrio.text(YELLOW, VIOLET, YELLOW))\n\n    @Ignore\n    @Test\n    fun `yellow violet violet`() = assertEquals(\"470 megaohms\", ResistorColorTrio.text(YELLOW, VIOLET, VIOLET))\n}\n"
  },
  {
    "path": "exercises/practice/reverse-string/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to reverse a given string.\n\nSome examples:\n\n- Turn `\"stressed\"` into `\"desserts\"`.\n- Turn `\"strops\"` into `\"sports\"`.\n- Turn `\"racecar\"` into `\"racecar\"`.\n"
  },
  {
    "path": "exercises/practice/reverse-string/.docs/introduction.md",
    "content": "# Introduction\n\nReversing strings (reading them from right to left, rather than from left to right) is a surprisingly common task in programming.\n\nFor example, in bioinformatics, reversing the sequence of DNA or RNA strings is often important for various analyses, such as finding complementary strands or identifying palindromic sequences that have biological significance.\n"
  },
  {
    "path": "exercises/practice/reverse-string/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"vmichalak\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"mikegehard\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/ReverseString.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ReverseStringTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/ReverseString.kt\"\n    ]\n  },\n  \"blurb\": \"Reverse a given string.\",\n  \"source\": \"Introductory challenge to reverse an input string\",\n  \"source_url\": \"https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb\"\n}\n"
  },
  {
    "path": "exercises/practice/reverse-string/.meta/src/reference/kotlin/ReverseString.kt",
    "content": "fun reverse(input: String): String {\n    val result = StringBuilder()\n    for(i in input.indices) {\n        result.append(input[input.length - 1 - i])\n    }\n    return result.toString()\n}"
  },
  {
    "path": "exercises/practice/reverse-string/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# an empty string\n\"c3b7d806-dced-49ee-8543-933fd1719b1c\" = true\n\n# a word\n\"01ebf55b-bebb-414e-9dec-06f7bb0bee3c\" = true\n\n# a capitalized word\n\"0f7c07e4-efd1-4aaa-a07a-90b49ce0b746\" = true\n\n# a sentence with punctuation\n\"71854b9c-f200-4469-9f5c-1e8e5eff5614\" = true\n\n# a palindrome\n\"1f8ed2f3-56f3-459b-8f3e-6d8d654a1f6c\" = true\n\n# an even-sized word\n\"b9e7dec1-c6df-40bd-9fa3-cd7ded010c4c\" = true\n"
  },
  {
    "path": "exercises/practice/reverse-string/.meta/version",
    "content": "1.2.0"
  },
  {
    "path": "exercises/practice/reverse-string/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/reverse-string/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/reverse-string/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/reverse-string/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/reverse-string/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/reverse-string/src/main/kotlin/ReverseString.kt",
    "content": "fun reverse(input: String): String {\n    TODO(\"Implement this function to complete the task\")\n}\n"
  },
  {
    "path": "exercises/practice/reverse-string/src/test/kotlin/ReverseStringTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass ReverseStringTest {\n    @Test\n    fun `empty string`() = assertEquals(\"\", reverse(\"\"))\n\n    @Ignore\n    @Test\n    fun `single word`() = assertEquals(\"tobor\", reverse(\"robot\"))\n\n    @Ignore\n    @Test\n    fun `capitalized word`() = assertEquals(\"nemaR\", reverse(\"Ramen\"))\n\n    @Ignore\n    @Test\n    fun `sentence with punctuation`() = assertEquals(\"!yrgnuh m'I\", reverse(\"I'm hungry!\"))\n\n    @Ignore\n    @Test\n    fun `palindrome word`() = assertEquals(\"racecar\", reverse(\"racecar\"))\n\n    @Ignore\n    @Test\n    fun `even-sized word`() = assertEquals(\"reward\", reverse(\"drawer\"))\n\n    @Ignore\n    @Test\n    fun `apply twice`() {\n        val input = \"input\"\n        assertEquals(input, reverse(reverse(input)))\n    }\n}\n"
  },
  {
    "path": "exercises/practice/rna-transcription/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to determine the RNA complement of a given DNA sequence.\n\nBoth DNA and RNA strands are a sequence of nucleotides.\n\nThe four nucleotides found in DNA are adenine (**A**), cytosine (**C**), guanine (**G**), and thymine (**T**).\n\nThe four nucleotides found in RNA are adenine (**A**), cytosine (**C**), guanine (**G**), and uracil (**U**).\n\nGiven a DNA strand, its transcribed RNA strand is formed by replacing each nucleotide with its complement:\n\n- `G` -> `C`\n- `C` -> `G`\n- `T` -> `A`\n- `A` -> `U`\n\n~~~~exercism/note\nIf you want to look at how the inputs and outputs are structured, take a look at the examples in the test suite.\n~~~~\n"
  },
  {
    "path": "exercises/practice/rna-transcription/.docs/introduction.md",
    "content": "# Introduction\n\nYou work for a bioengineering company that specializes in developing therapeutic solutions.\n\nYour team has just been given a new project to develop a targeted therapy for a rare type of cancer.\n\n~~~~exercism/note\nIt's all very complicated, but the basic idea is that sometimes people's bodies produce too much of a given protein.\nThat can cause all sorts of havoc.\n\nBut if you can create a very specific molecule (called a micro-RNA), it can prevent the protein from being produced.\n\nThis technique is called [RNA Interference][rnai].\n\n[rnai]: https://admin.acceleratingscience.com/ask-a-scientist/what-is-rnai/\n~~~~\n"
  },
  {
    "path": "exercises/practice/rna-transcription/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"enixander\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"mutexkid\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/RnaTranscription.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/RnaTranscriptionTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/RnaTranscription.kt\"\n    ]\n  },\n  \"blurb\": \"Given a DNA strand, return its RNA complement.\",\n  \"source\": \"Hyperphysics\",\n  \"source_url\": \"https://web.archive.org/web/20220408112140/http://hyperphysics.phy-astr.gsu.edu/hbase/Organic/transcription.html\"\n}\n"
  },
  {
    "path": "exercises/practice/rna-transcription/.meta/src/reference/kotlin/RnaTranscription.kt",
    "content": "fun transcribeToRna(dna: String): String = dna.map { nucleotide ->\n    when (nucleotide) {\n        'A' -> 'U'\n        'G' -> 'C'\n        'C' -> 'G'\n        'T' -> 'A'\n        else -> nucleotide\n    }\n}.joinToString(\"\")\n"
  },
  {
    "path": "exercises/practice/rna-transcription/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# Empty RNA sequence\n\"b4631f82-c98c-4a2f-90b3-c5c2b6c6f661\" = true\n\n# RNA complement of cytosine is guanine\n\"a9558a3c-318c-4240-9256-5d5ed47005a6\" = true\n\n# RNA complement of guanine is cytosine\n\"6eedbb5c-12cb-4c8b-9f51-f8320b4dc2e7\" = true\n\n# RNA complement of thymine is adenine\n\"870bd3ec-8487-471d-8d9a-a25046488d3e\" = true\n\n# RNA complement of adenine is uracil\n\"aade8964-02e1-4073-872f-42d3ffd74c5f\" = true\n\n# RNA complement\n\"79ed2757-f018-4f47-a1d7-34a559392dbf\" = true\n"
  },
  {
    "path": "exercises/practice/rna-transcription/.meta/version",
    "content": "1.3.0\n"
  },
  {
    "path": "exercises/practice/rna-transcription/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/rna-transcription/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/rna-transcription/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/rna-transcription/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/rna-transcription/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/rna-transcription/src/main/kotlin/RnaTranscription.kt",
    "content": "fun transcribeToRna(dna: String): String = \"\"\n"
  },
  {
    "path": "exercises/practice/rna-transcription/src/test/kotlin/RnaTranscriptionTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass RnaTranscriptionTest {\n    @Test\n    fun `empty RNA` ()= assertEquals(\"\", transcribeToRna(\"\"))\n\n    @Test\n    @Ignore\n    fun `RNA complement of cytosine is guanine`() = assertEquals(\"G\", transcribeToRna(\"C\"))\n\n    @Ignore\n    @Test\n    fun `RNA complement of guanine is cytosine`() = assertEquals(\"C\", transcribeToRna(\"G\"))\n\n    @Ignore\n    @Test\n    fun `RNA complement of thymine is adenine`() = assertEquals(\"A\", transcribeToRna(\"T\"))\n\n    @Ignore\n    @Test\n    fun `RNA complement of adenine is uracil`() = assertEquals(\"U\", transcribeToRna(\"A\"))\n\n    @Ignore\n    @Test\n    fun `compound RNA`() = assertEquals(\"UGCACCAGAAUU\", transcribeToRna(\"ACGTGGTCTTAA\"))\n}\n"
  },
  {
    "path": "exercises/practice/robot-name/.docs/instructions.md",
    "content": "# Instructions\n\nManage robot factory settings.\n\nWhen a robot comes off the factory floor, it has no name.\n\nThe first time you turn on a robot, a random name is generated in the format of two uppercase letters followed by three digits, such as RX837 or BC811.\n\nEvery once in a while we need to reset a robot to its factory settings, which means that its name gets wiped.\nThe next time you ask, that robot will respond with a new random name.\n\nThe names must be random: they should not follow a predictable sequence.\nUsing random names means a risk of collisions.\nYour solution must ensure that every existing robot has a unique name.\n"
  },
  {
    "path": "exercises/practice/robot-name/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"mikegehard\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/RobotName.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/RobotTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/RobotName.kt\"\n    ]\n  },\n  \"blurb\": \"Manage robot factory settings.\",\n  \"source\": \"A debugging session with Paul Blackwell at gSchool.\"\n}\n"
  },
  {
    "path": "exercises/practice/robot-name/.meta/src/reference/kotlin/RobotName.kt",
    "content": "class Robot {\n    companion object {\n        val existingNames = mutableSetOf<String>()\n    }\n\n    private var _name: String = generateName()\n    val name: String\n        get() = _name\n\n    fun reset() {\n        _name = generateName()\n    }\n\n    private tailrec fun generateName(): String {\n        val randomLetters = ('A'..'Z').randomSample(2)\n        val numbers = (0..9).randomSample(3)\n        val newName = (randomLetters + numbers).joinToString(\"\")\n\n        return when {\n            existingNames.add(newName) -> newName\n            else -> generateName()\n        }\n    }\n\n    private fun <T> Iterable<T>.randomSample(number: Int): Iterable<T> =\n        (0 until number).map { this.shuffled()[0] }\n}\n"
  },
  {
    "path": "exercises/practice/robot-name/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/robot-name/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/robot-name/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/robot-name/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/robot-name/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/robot-name/src/main/kotlin/RobotName.kt",
    "content": "class Robot {\n\n    val name: String\n        get() = TODO(\"Implement this getter to complete the task\")\n\n    fun reset() {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/robot-name/src/test/kotlin/RobotTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\nimport kotlin.test.assertNotEquals\nimport kotlin.test.assertTrue\n\nclass RobotTest {\n\n    companion object {\n        val EXPECTED_ROBOT_NAME_PATTERN = Regex(\"[A-Z]{2}\\\\d{3}\")\n        private fun isValidName(name: String) = EXPECTED_ROBOT_NAME_PATTERN.matches(name)\n    }\n\n    val robot = Robot()\n\n\n    @Test\n    fun hasName() {\n        assertTrue(isValidName(robot.name), \"Robot name ${robot.name} didn't match expected pattern.\")\n    }\n\n    @Ignore\n    @Test\n    fun differentRobotsHaveDifferentNames() {\n        assertNotEquals(robot.name, Robot().name)\n    }\n    \n    @Ignore\n    @Test\n    fun robotRemembersItsName() {\n        assertEquals(robot.name, robot.name)\n    }\n\n    @Ignore\n    @Test\n    fun resetName() {\n        val name = robot.name\n        robot.reset()\n\n        val name2 = robot.name\n        assertNotEquals(name, name2)\n        assertTrue(isValidName(name2), \"Robot name $name2 didn't match expected pattern.\")\n    }\n\n    @Ignore\n    @Test\n    fun isRandom() {\n        val iterations = 100000\n        val names = (0 until iterations).map { Robot().name }\n        assertEquals(iterations, names.size)\n        assertEquals(iterations, names.distinct().size)\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/robot-simulator/.docs/instructions.md",
    "content": "# Instructions\n\nWrite a robot simulator.\n\nA robot factory's test facility needs a program to verify robot movements.\n\nThe robots have three possible movements:\n\n- turn right\n- turn left\n- advance\n\nRobots are placed on a hypothetical infinite grid, facing a particular direction (north, east, south, or west) at a set of {x,y} coordinates,\ne.g., {3,8}, with coordinates increasing to the north and east.\n\nThe robot then receives a number of instructions, at which point the testing facility verifies the robot's new position, and in which direction it is pointing.\n\n- The letter-string \"RAALAL\" means:\n  - Turn right\n  - Advance twice\n  - Turn left\n  - Advance once\n  - Turn left yet again\n- Say a robot starts at {7, 3} facing north.\n  Then running this stream of instructions should leave it at {9, 4} facing west.\n"
  },
  {
    "path": "exercises/practice/robot-simulator/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"sup95\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Robot.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/RobotTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Robot.kt\"\n    ]\n  },\n  \"blurb\": \"Write a robot simulator.\",\n  \"source\": \"Inspired by an interview question at a famous company.\"\n}\n"
  },
  {
    "path": "exercises/practice/robot-simulator/.meta/src/reference/kotlin/GridPosition.kt",
    "content": "data class GridPosition(val x: Int, val y: Int)\n"
  },
  {
    "path": "exercises/practice/robot-simulator/.meta/src/reference/kotlin/Orientation.kt",
    "content": "enum class Orientation {\n\n    NORTH, EAST, SOUTH, WEST\n\n}\n"
  },
  {
    "path": "exercises/practice/robot-simulator/.meta/src/reference/kotlin/Robot.kt",
    "content": "fun Orientation.turnLeft()  = Orientation.values()[Math.floorMod(ordinal - 1, Orientation.values().size)]\nfun Orientation.turnRight() = Orientation.values()[Math.floorMod(ordinal + 1, Orientation.values().size)]\n\nclass Robot(var gridPosition: GridPosition = GridPosition(0, 0), var orientation: Orientation = Orientation.NORTH) {\n\n    private fun advance() {\n        gridPosition = when (orientation) {\n            Orientation.NORTH -> gridPosition.copy(y = gridPosition.y + 1)\n            Orientation.EAST  -> gridPosition.copy(x = gridPosition.x + 1)\n            Orientation.SOUTH -> gridPosition.copy(y = gridPosition.y - 1)\n            Orientation.WEST  -> gridPosition.copy(x = gridPosition.x - 1)\n        }\n    }\n\n    private fun turnLeft() {\n        orientation = orientation.turnLeft()\n    }\n\n    private fun turnRight() {\n        orientation = orientation.turnRight()\n    }\n\n    fun simulate(instructions: String) {\n        for (instruction in instructions) {\n            when (instruction) {\n                'A' -> advance()\n                'R' -> turnRight()\n                'L' -> turnLeft()\n                else -> throw IllegalArgumentException(String.format(\"Invalid instruction: '%s'\", instruction))\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/robot-simulator/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# at origin facing north\n\"c557c16d-26c1-4e06-827c-f6602cd0785c\" = true\n\n# at negative position facing south\n\"bf0dffce-f11c-4cdb-8a5e-2c89d8a5a67d\" = true\n\n# changes north to east\n\"8cbd0086-6392-4680-b9b9-73cf491e67e5\" = true\n\n# changes east to south\n\"8abc87fc-eab2-4276-93b7-9c009e866ba1\" = true\n\n# changes south to west\n\"3cfe1b85-bbf2-4bae-b54d-d73e7e93617a\" = true\n\n# changes west to north\n\"5ea9fb99-3f2c-47bd-86f7-46b7d8c3c716\" = true\n\n# changes north to west\n\"fa0c40f5-6ba3-443d-a4b3-58cbd6cb8d63\" = true\n\n# changes west to south\n\"da33d734-831f-445c-9907-d66d7d2a92e2\" = true\n\n# changes south to east\n\"bd1ca4b9-4548-45f4-b32e-900fc7c19389\" = true\n\n# changes east to north\n\"2de27b67-a25c-4b59-9883-bc03b1b55bba\" = true\n\n# facing north increments Y\n\"f0dc2388-cddc-4f83-9bed-bcf46b8fc7b8\" = true\n\n# facing south decrements Y\n\"2786cf80-5bbf-44b0-9503-a89a9c5789da\" = true\n\n# facing east increments X\n\"84bf3c8c-241f-434d-883d-69817dbd6a48\" = true\n\n# facing west decrements X\n\"bb69c4a7-3bbf-4f64-b415-666fa72d7b04\" = true\n\n# moving east and north from README\n\"e34ac672-4ed4-4be3-a0b8-d9af259cbaa1\" = true\n\n# moving west and north\n\"f30e4955-4b47-4aa3-8b39-ae98cfbd515b\" = true\n\n# moving west and south\n\"3e466bf6-20ab-4d79-8b51-264165182fca\" = true\n\n# moving east and north\n\"41f0bb96-c617-4e6b-acff-a4b279d44514\" = true\n"
  },
  {
    "path": "exercises/practice/robot-simulator/.meta/version",
    "content": "3.2.0"
  },
  {
    "path": "exercises/practice/robot-simulator/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/robot-simulator/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/robot-simulator/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/robot-simulator/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/robot-simulator/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/robot-simulator/src/main/kotlin/GridPosition.kt",
    "content": "data class GridPosition(val x: Int, val y: Int)\n"
  },
  {
    "path": "exercises/practice/robot-simulator/src/main/kotlin/Orientation.kt",
    "content": "enum class Orientation {\n\n    NORTH, EAST, SOUTH, WEST\n\n}\n"
  },
  {
    "path": "exercises/practice/robot-simulator/src/main/kotlin/Robot.kt",
    "content": "class Robot {\n\n    // TODO: implement proper constructor, provide read access to `gridPosition` and `orientation`\n\n    fun simulate(instructions: String) {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/robot-simulator/src/test/kotlin/RobotTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass RobotTest {\n\n    @Test\n    fun `brand new - at origin facing north`() =\n        Robot()\n            .should {\n                face(Orientation.NORTH)\n                beAt(x = 0, y = 0)\n            }\n\n    @Ignore\n    @Test\n    fun `brand new - at negative position facing south`() =\n        Robot(GridPosition(x = -1, y = -1), Orientation.SOUTH)\n            .should {\n                face(Orientation.SOUTH)\n                beAt(x = -1, y = -1)\n            }\n\n    @Ignore\n    @Test\n    fun `rotating clockwise - changes north to east`() =\n        Robot(GridPosition(x = 0, y = 0), Orientation.NORTH)\n            .instructed(\"R\")\n            .should {\n                face(Orientation.EAST)\n            }\n\n    @Ignore\n    @Test\n    fun `rotating clockwise - changes east to south`() =\n        Robot(GridPosition(x = 0, y = 0), Orientation.EAST)\n            .instructed(\"R\")\n            .should {\n                face(Orientation.SOUTH)\n            }\n\n    @Ignore\n    @Test\n    fun `rotating clockwise - changes south to west`() =\n        Robot(GridPosition(x = 0, y = 0), Orientation.SOUTH)\n            .instructed(\"R\")\n            .should {\n                face(Orientation.WEST)\n            }\n\n    @Ignore\n    @Test\n    fun `rotating clockwise - changes west to north`() =\n        Robot(GridPosition(x = 0, y = 0), Orientation.WEST)\n            .instructed(\"R\")\n            .should {\n                face(Orientation.NORTH)\n            }\n\n    @Ignore\n    @Test\n    fun `rotating counter-clockwise - changes north to west`() =\n        Robot(GridPosition(x = 0, y = 0), Orientation.NORTH)\n            .instructed(\"L\")\n            .should {\n                face(Orientation.WEST)\n            }\n\n    @Ignore\n    @Test\n    fun `rotating counter-clockwise - changes west to south`() =\n        Robot(GridPosition(x = 0, y = 0), Orientation.WEST)\n            .instructed(\"L\")\n            .should {\n                face(Orientation.SOUTH)\n            }\n\n    @Ignore\n    @Test\n    fun `rotating counter-clockwise - changes south to east`() =\n        Robot(GridPosition(x = 0, y = 0), Orientation.SOUTH)\n            .instructed(\"L\")\n            .should {\n                face(Orientation.EAST)\n            }\n\n    @Ignore\n    @Test\n    fun `rotating counter-clockwise - changes east to north`() =\n        Robot(GridPosition(x = 0, y = 0), Orientation.EAST)\n            .instructed(\"L\")\n            .should {\n                face(Orientation.NORTH)\n            }\n\n    @Ignore\n    @Test\n    fun `moving forward - facing north increments Y`() =\n        Robot(GridPosition(x = 0, y = 0), Orientation.NORTH)\n            .instructed(\"A\")\n            .should {\n                face(Orientation.NORTH)\n                beAt(x = 0, y = 1)\n            }\n\n    @Ignore\n    @Test\n    fun `moving forward - facing south decrements Y`() =\n        Robot(GridPosition(x = 0, y = 0), Orientation.SOUTH)\n            .instructed(\"A\")\n            .should {\n                face (Orientation.SOUTH)\n                beAt(x = 0, y = -1)\n            }\n\n    @Ignore\n    @Test\n    fun `moving forward - facing east increments X`() =\n        Robot(GridPosition(x = 0, y = 0), Orientation.EAST)\n            .instructed(\"A\")\n            .should {\n                face (Orientation.EAST)\n                beAt(x = 1, y = 0)\n            }\n\n    @Ignore\n    @Test\n    fun `moving forward - facing west decrements X`() =\n        Robot(GridPosition(x = 0, y = 0), Orientation.WEST)\n            .instructed(\"A\")\n            .should {\n                face (Orientation.WEST)\n                beAt(x = -1, y = 0)\n            }\n\n    @Ignore\n    @Test\n    fun `series of instructions - moving east and north example`() =\n        Robot(GridPosition(x = 7, y = 3), Orientation.NORTH)\n            .instructed(\"RAALAL\")\n            .should {\n                face(Orientation.WEST)\n                beAt(x = 9, y = 4)\n            }\n\n    @Ignore\n    @Test\n    fun `series of instructions - moving west and north`() =\n        Robot(GridPosition(x = 0, y = 0), Orientation.NORTH)\n            .instructed(\"LAAARALA\")\n            .should {\n                face(Orientation.WEST)\n                beAt(x = -4, y = 1)\n            }\n\n    @Ignore\n    @Test\n    fun `series of instructions - moving west and south`() =\n        Robot(GridPosition(x = 2, y = -7), Orientation.EAST)\n            .instructed(\"RRAAAAALA\")\n            .should {\n                face(Orientation.SOUTH)\n                beAt(x = -3, y = -8)\n            }\n\n    @Ignore\n    @Test\n    fun `series of instructions - moving east and north`() =\n        Robot(GridPosition(x = 8, y = 4), Orientation.SOUTH)\n            .instructed(\"LAAARRRALLLL\")\n            .should {\n                face(Orientation.NORTH)\n                beAt(x = 11, y = 5)\n            }\n}\n\nprivate fun Robot.instructed(moves: String): Robot {\n    simulate(moves)\n    return this\n}\n\nprivate fun Robot.should(what: RobotShould.() -> Unit) = what(RobotShould(this))\n\nprivate class RobotShould(private val robot: Robot) {\n    fun face(expected: Orientation) = assertEquals(expected, robot.orientation)\n    fun beAt(x: Int, y: Int) = assertEquals(GridPosition(x = x, y = y), robot.gridPosition)\n}\n"
  },
  {
    "path": "exercises/practice/roman-numerals/.approaches/config.json",
    "content": "{\n  \"introduction\": {\n    \"authors\": [\n      \"bobahop\"\n    ]\n  },\n  \"approaches\": [\n    {\n      \"uuid\": \"96ce2094-949d-4576-a2d1-ab8a76081225\",\n      \"slug\": \"fold-repeat\",\n      \"title\": \"fold with repeat\",\n      \"blurb\": \"Use fold with repeat to return the answer.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "exercises/practice/roman-numerals/.approaches/fold-repeat/content.md",
    "content": "# `fold` with `repeat`\n\n```kotlin\nobject RomanNumerals {\n\n    fun value(n: Int) =\n            listOf(\n                            1000 to \"M\",\n                            900 to \"CM\",\n                            500 to \"D\",\n                            400 to \"CD\",\n                            100 to \"C\",\n                            90 to \"XC\",\n                            50 to \"L\",\n                            40 to \"XL\",\n                            10 to \"X\",\n                            9 to \"IX\",\n                            5 to \"V\",\n                            4 to \"IV\",\n                            1 to \"I\"\n                    )\n                    .fold(Pair(StringBuilder(), n)) { (output, runnyNum), (value, numeral) ->\n                        when {\n                            runnyNum >= value ->\n                                    output.append(numeral.repeat(runnyNum / value)) to\n                                            runnyNum % value\n                            else -> output to runnyNum\n                        }\n                    }\n                    .first\n                    .toString()\n}\n```\n\nAn [object declaration][object] is used to define `RomanNumerals` as essentially a [singleton][singleton] object instantiation of the class.\nThis is sufficient, since there is no object state that needs to change with each call of the `value` method.\n\nThe [`listOf`][listof] method is used to create a list of [`Pair`][pair]s that associate an Arabic numeral with its Roman numeral.\n\nThe [`fold`][fold] method is called on the `List`.\nIts accumulating value is initialized with a `Pair`, with a [`StringBuilder`][stringbuilder] for the output and an `Int` to hold the value of the input number\nas it is calculated down.\n\nThe [lambda][lambda] of `fold` takes the accumulating value `Pair` as well as the `Pair` of each `List` element being iterated.\n\nThe running number is tested in a [`when`][when] expression.\nIf it is greater than or equal to the Arabic value in the currently iterated `Pair`,\nthen the [`repeat`][repeat] method is used to [`append`][append] the Roman numeral to the `StringBuilder`\nfor as many times as the running number can be divided by the Arabic value with a result greater than 0.\nThat arm of the `when` uses the [`to`][to] keyword to return the `StringBuilder` and the remainder of dividing the running number by the Arabic value.\n\nIf the running number is less than the Arabic value, then the `when` expression returns the `StringBuilder` and the running number as is.\n\nWhen `fold` has iterated through all of the `List` elements, the first item in the accumulating value `Pair` is the `StringBuilder`.\nThe `value` function returns the result of calling the [`toString`][tostring] method on the `StringBuilder`.\n\nAlthough the `value` function has multiple lines, it consists only of the one expression of chained methods, so it is defined using\n[single-expression function][single-expression-function] syntax, with the curly braces omitted and the return type [inferred][type-inference].\n\n[object]: https://kotlinlang.org/docs/object-declarations.html#object-declarations-overview\n[singleton]: https://en.wikipedia.org/wiki/Singleton_pattern\n[listof]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/list-of.html\n[list]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/\n[pair]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-pair/\n[fold]: https://kotlinlang.org/docs/collection-aggregate.html#fold-and-reduce\n[stringbuilder]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-string-builder/\n[when]: https://kotlinlang.org/docs/control-flow.html#when-expression\n[lambda]: https://kotlinlang.org/docs/lambdas.html#lambda-expressions-and-anonymous-functions\n[append]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-string-builder/append.html\n[repeat]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/repeat.html\n[to]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/to.html\n[tostring]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-string-builder/to-string.html\n[single-expression-function]: https://kotlinlang.org/docs/functions.html#single-expression-functions\n[type-inference]: https://kotlinlang.org/spec/type-inference.html\n"
  },
  {
    "path": "exercises/practice/roman-numerals/.approaches/fold-repeat/snippet.txt",
    "content": ".fold(Pair(StringBuilder(), n)) { (output, runnyNum), (value, numeral) ->\n    when {\n        runnyNum >= value ->\n                output.append(numeral.repeat(runnyNum / value)) to\n                        runnyNum % value\n        else -> output to runnyNum\n    }\n}\n"
  },
  {
    "path": "exercises/practice/roman-numerals/.approaches/introduction.md",
    "content": "# Introduction\n\nThere are many ways to solve Roman Numerals.\nOne approach can use the [`fold`][fold] method on a list of [`Pair`][pair]s that associate the Arabic numeral with the Roman numeral.\n\n## Approach: `fold` with `repeat`\n\n```kotlin\nobject RomanNumerals {\n\n    fun value(n: Int) =\n            listOf(\n                            1000 to \"M\",\n                            900 to \"CM\",\n                            500 to \"D\",\n                            400 to \"CD\",\n                            100 to \"C\",\n                            90 to \"XC\",\n                            50 to \"L\",\n                            40 to \"XL\",\n                            10 to \"X\",\n                            9 to \"IX\",\n                            5 to \"V\",\n                            4 to \"IV\",\n                            1 to \"I\"\n                    )\n                    .fold(Pair(StringBuilder(), n)) { (output, runnyNum), (value, numeral) ->\n                        when {\n                            runnyNum >= value ->\n                                    output.append(numeral.repeat(runnyNum / value)) to\n                                            runnyNum % value\n                            else -> output to runnyNum\n                        }\n                    }\n                    .first\n                    .toString()\n}\n```\n\nFor more information, check the [`fold` with `repeat` approach][approach-fold-repeat].\n\n[approach-fold-repeat]: https://exercism.org/tracks/kotlin/exercises/roman-numerals/approaches/fold-repeat\n\n[fold]: https://kotlinlang.org/docs/collection-aggregate.html#fold-and-reduce\n[pair]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-pair/\n"
  },
  {
    "path": "exercises/practice/roman-numerals/.docs/instructions.md",
    "content": "# Introduction\n\nYour task is to convert a number from Arabic numerals to Roman numerals.\n\nFor this exercise, we are only concerned about traditional Roman numerals, in which the largest number is MMMCMXCIX (or 3,999).\n\n~~~~exercism/note\nThere are lots of different ways to convert between Arabic and Roman numerals.\nWe recommend taking a naive approach first to familiarise yourself with the concept of Roman numerals and then search for more efficient methods.\n\nMake sure to check out our Deep Dive video at the end to explore the different approaches you can take!\n~~~~\n"
  },
  {
    "path": "exercises/practice/roman-numerals/.docs/introduction.md",
    "content": "# Description\n\nToday, most people in the world use Arabic numerals (0–9).\nBut if you travelled back two thousand years, you'd find that most Europeans were using Roman numerals instead.\n\nTo write a Roman numeral we use the following Latin letters, each of which has a value:\n\n| M    | D   | C   | L   | X   | V   | I   |\n| ---- | --- | --- | --- | --- | --- | --- |\n| 1000 | 500 | 100 | 50  | 10  | 5   | 1   |\n\nA Roman numeral is a sequence of these letters, and its value is the sum of the letters' values.\nFor example, `XVIII` has the value 18 (`10 + 5 + 1 + 1 + 1 = 18`).\n\nThere's one rule that makes things trickier though, and that's that **the same letter cannot be used more than three times in succession**.\nThat means that we can't express numbers such as 4 with the seemingly natural `IIII`.\nInstead, for those numbers, we use a subtraction method between two letters.\nSo we think of `4` not as `1 + 1 + 1 + 1` but instead as `5 - 1`.\nAnd slightly confusingly to our modern thinking, we write the smaller number first.\nThis applies only in the following cases: 4 (`IV`), 9 (`IX`), 40 (`XL`), 90 (`XC`), 400 (`CD`) and 900 (`CM`).\n\nOrder matters in Roman numerals!\nLetters (and the special compounds above) must be ordered by decreasing value from left to right.\n\nHere are some examples:\n\n```text\n 105 => CV\n---- => --\n 100 => C\n+  5 =>  V\n```\n\n```text\n 106 => CVI\n---- => --\n 100 => C\n+  5 =>  V\n+  1 =>   I\n```\n\n```text\n 104 => CIV\n---- => ---\n 100 => C\n+  4 =>  IV\n```\n\nAnd a final more complex example:\n\n```text\n 1996 => MCMXCVI\n----- => -------\n 1000 => M\n+ 900 =>  CM\n+  90 =>    XC\n+   5 =>      V\n+   1 =>       I\n```\n"
  },
  {
    "path": "exercises/practice/roman-numerals/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"sup95\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/RomanNumerals.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/RomanNumeralsTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/RomanNumerals.kt\"\n    ]\n  },\n  \"blurb\": \"Convert modern Arabic numbers into Roman numerals.\",\n  \"source\": \"The Roman Numeral Kata\",\n  \"source_url\": \"https://codingdojo.org/kata/RomanNumerals/\"\n}\n"
  },
  {
    "path": "exercises/practice/roman-numerals/.meta/src/reference/kotlin/RomanNumerals.kt",
    "content": "object RomanNumerals {\n\n    private val numeralValues = listOf(\n            Pair(1000, \"M\"),\n            Pair(900, \"CM\"),\n            Pair(500, \"D\"),\n            Pair(400, \"CD\"),\n            Pair(100, \"C\"),\n            Pair(90, \"XC\"),\n            Pair(50, \"L\"),\n            Pair(40, \"XL\"),\n            Pair(10, \"X\"),\n            Pair(9, \"IX\"),\n            Pair(5, \"V\"),\n            Pair(4, \"IV\"),\n            Pair(1, \"I\")\n    )\n\n\n    private tailrec fun fromNumber(n: Int, numerals: String): String {\n        val numeralPair = numeralValues.find { it.first <= n }\n        if (numeralPair != null) {\n            return fromNumber(n - numeralPair.first, numerals + numeralPair.second)\n        }\n\n        return numerals\n    }\n\n    fun value(n: Int) = fromNumber(n, \"\")\n}\n"
  },
  {
    "path": "exercises/practice/roman-numerals/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# 1 is a single I\n\"19828a3a-fbf7-4661-8ddd-cbaeee0e2178\" = true\n\n# 2 is two I's\n\"f088f064-2d35-4476-9a41-f576da3f7b03\" = true\n\n# 3 is three I's\n\"b374a79c-3bea-43e6-8db8-1286f79c7106\" = true\n\n# 4, being 5 - 1, is IV\n\"05a0a1d4-a140-4db1-82e8-fcc21fdb49bb\" = true\n\n# 5 is a single V\n\"57c0f9ad-5024-46ab-975d-de18c430b290\" = true\n\n# 6, being 5 + 1, is VI\n\"20a2b47f-e57f-4797-a541-0b3825d7f249\" = true\n\n# 9, being 10 - 1, is IX\n\"ff3fb08c-4917-4aab-9f4e-d663491d083d\" = true\n\n# 20 is two X's\n\"2bda64ca-7d28-4c56-b08d-16ce65716cf6\" = true\n\n# 48 is not 50 - 2 but rather 40 + 8\n\"a1f812ef-84da-4e02-b4f0-89c907d0962c\" = true\n\n# 49 is not 40 + 5 + 4 but rather 50 - 10 + 10 - 1\n\"607ead62-23d6-4c11-a396-ef821e2e5f75\" = true\n\n# 50 is a single L\n\"d5b283d4-455d-4e68-aacf-add6c4b51915\" = true\n\n# 90, being 100 - 10, is XC\n\"46b46e5b-24da-4180-bfe2-2ef30b39d0d0\" = true\n\n# 100 is a single C\n\"30494be1-9afb-4f84-9d71-db9df18b55e3\" = true\n\n# 60, being 50 + 10, is LX\n\"267f0207-3c55-459a-b81d-67cec7a46ed9\" = true\n\n# 400, being 500 - 100, is CD\n\"cdb06885-4485-4d71-8bfb-c9d0f496b404\" = true\n\n# 500 is a single D\n\"6b71841d-13b2-46b4-ba97-dec28133ea80\" = true\n\n# 900, being 1000 - 100, is CM\n\"432de891-7fd6-4748-a7f6-156082eeca2f\" = true\n\n# 1000 is a single M\n\"e6de6d24-f668-41c0-88d7-889c0254d173\" = true\n\n# 3000 is three M's\n\"bb550038-d4eb-4be2-a9ce-f21961ac3bc6\" = true\n"
  },
  {
    "path": "exercises/practice/roman-numerals/.meta/version",
    "content": "1.2.0\n"
  },
  {
    "path": "exercises/practice/roman-numerals/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/roman-numerals/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/roman-numerals/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/roman-numerals/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/roman-numerals/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/roman-numerals/src/main/kotlin/RomanNumerals.kt",
    "content": "object RomanNumerals {\n\n    fun value(n: Int): String {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/roman-numerals/src/test/kotlin/RomanNumeralsTest.kt",
    "content": "import org.junit.Test\nimport org.junit.runner.RunWith\nimport org.junit.runners.Parameterized\nimport kotlin.test.assertEquals\n\n@RunWith(Parameterized::class)\nclass RomanNumeralsTest(val input: Int, val expectedOutput: String) {\n\n    companion object {\n        @JvmStatic\n        @Parameterized.Parameters(name = \"{index}: romanNumeral({0})={1}\")\n        fun data() = listOf(\n                arrayOf(1, \"I\"),\n                arrayOf(2, \"II\"),\n                arrayOf(3, \"III\"),\n                arrayOf(4, \"IV\"),\n                arrayOf(5, \"V\"),\n                arrayOf(6, \"VI\"),\n                arrayOf(9, \"IX\"),\n                arrayOf(27, \"XXVII\"),\n                arrayOf(48, \"XLVIII\"),\n                arrayOf(49, \"XLIX\"),\n                arrayOf(59, \"LIX\"),\n                arrayOf(93, \"XCIII\"),\n                arrayOf(141, \"CXLI\"),\n                arrayOf(163, \"CLXIII\"),\n                arrayOf(402, \"CDII\"),\n                arrayOf(575, \"DLXXV\"),\n                arrayOf(911, \"CMXI\"),\n                arrayOf(1024, \"MXXIV\"),\n                arrayOf(3000, \"MMM\")\n        )\n    }\n\n    @Test\n    fun test() {\n        assertEquals(expectedOutput, RomanNumerals.value(input))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/rotational-cipher/.docs/instructions.md",
    "content": "# Instructions\n\nCreate an implementation of the rotational cipher, also sometimes called the Caesar cipher.\n\nThe Caesar cipher is a simple shift cipher that relies on transposing all the letters in the alphabet using an integer key between `0` and `26`.\nUsing a key of `0` or `26` will always yield the same output due to modular arithmetic.\nThe letter is shifted for as many values as the value of the key.\n\nThe general notation for rotational ciphers is `ROT + <key>`.\nThe most commonly used rotational cipher is `ROT13`.\n\nA `ROT13` on the Latin alphabet would be as follows:\n\n```text\nPlain:  abcdefghijklmnopqrstuvwxyz\nCipher: nopqrstuvwxyzabcdefghijklm\n```\n\nIt is stronger than the Atbash cipher because it has 27 possible keys, and 25 usable keys.\n\nCiphertext is written out in the same formatting as the input including spaces and punctuation.\n\n## Examples\n\n- ROT5 `omg` gives `trl`\n- ROT0 `c` gives `c`\n- ROT26 `Cool` gives `Cool`\n- ROT13 `The quick brown fox jumps over the lazy dog.` gives `Gur dhvpx oebja sbk whzcf bire gur ynml qbt.`\n- ROT13 `Gur dhvpx oebja sbk whzcf bire gur ynml qbt.` gives `The quick brown fox jumps over the lazy dog.`\n"
  },
  {
    "path": "exercises/practice/rotational-cipher/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/RotationalCipher.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/RotationalCipherTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/RotationalCipher.kt\"\n    ]\n  },\n  \"blurb\": \"Create an implementation of the rotational cipher, also sometimes called the Caesar cipher.\",\n  \"source\": \"Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Caesar_cipher\"\n}\n"
  },
  {
    "path": "exercises/practice/rotational-cipher/.meta/src/reference/kotlin/RotationalCipher.kt",
    "content": "class RotationalCipher(val shiftKey: Int) {\n\n    companion object {\n        private val LOWERS = ('a'..'z').toList()\n        private val UPPERS = ('A'..'Z').toList()\n    }\n\n    fun encode(text: String): String {\n        return text.map { char ->\n            when (char) {\n                in LOWERS -> LOWERS[(LOWERS.indexOf(char) + shiftKey) % LOWERS.size]\n                in UPPERS -> UPPERS[(UPPERS.indexOf(char) + shiftKey) % UPPERS.size]\n                else      -> char\n            }\n        }.joinToString(\"\")\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/rotational-cipher/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# rotate a by 0, same output as input\n\"74e58a38-e484-43f1-9466-877a7515e10f\" = true\n\n# rotate a by 1\n\"7ee352c6-e6b0-4930-b903-d09943ecb8f5\" = true\n\n# rotate a by 26, same output as input\n\"edf0a733-4231-4594-a5ee-46a4009ad764\" = true\n\n# rotate m by 13\n\"e3e82cb9-2a5b-403f-9931-e43213879300\" = true\n\n# rotate n by 13 with wrap around alphabet\n\"19f9eb78-e2ad-4da4-8fe3-9291d47c1709\" = true\n\n# rotate capital letters\n\"a116aef4-225b-4da9-884f-e8023ca6408a\" = true\n\n# rotate spaces\n\"71b541bb-819c-4dc6-a9c3-132ef9bb737b\" = true\n\n# rotate numbers\n\"ef32601d-e9ef-4b29-b2b5-8971392282e6\" = true\n\n# rotate punctuation\n\"32dd74f6-db2b-41a6-b02c-82eb4f93e549\" = true\n\n# rotate all letters\n\"9fb93fe6-42b0-46e6-9ec1-0bf0a062d8c9\" = true\n"
  },
  {
    "path": "exercises/practice/rotational-cipher/.meta/version",
    "content": "1.2.0\n"
  },
  {
    "path": "exercises/practice/rotational-cipher/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/rotational-cipher/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/rotational-cipher/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/rotational-cipher/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/rotational-cipher/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/rotational-cipher/src/main/kotlin/RotationalCipher.kt",
    "content": "class RotationalCipher {\n\n    // TODO: Implement proper constructor\n\n    fun encode(text: String): String {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/rotational-cipher/src/test/kotlin/RotationalCipherTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass RotationalCipherTest {\n\n    @Test\n    fun testRotateLowercaseABy0() {\n        val cipher = RotationalCipher(0)\n        assertEquals(\"a\", cipher.encode(\"a\"))\n    }\n\n    @Ignore\n    @Test\n    fun testRotateLowercaseABy1NoWrapAround() {\n        val cipher = RotationalCipher(1)\n        assertEquals(\"b\", cipher.encode(\"a\"))\n    }\n\n    @Ignore\n    @Test\n    fun testRotateLowercaseABy26SingleWrapAround() {\n        val cipher = RotationalCipher(26)\n        assertEquals(\"a\", cipher.encode(\"a\"))\n    }\n\n    @Ignore\n    @Test\n    fun testRotateLowercaseMBy13NoWrapAround() {\n        val cipher = RotationalCipher(13)\n        assertEquals(\"z\", cipher.encode(\"m\"))\n    }\n\n    @Ignore\n    @Test\n    fun testRotateLowercaseNBy1SingleWrapAround() {\n        val cipher = RotationalCipher(13)\n        assertEquals(\"a\", cipher.encode(\"n\"))\n    }\n\n    @Ignore\n    @Test\n    fun testRotateCapitalLettersNoWrapAround() {\n        val cipher = RotationalCipher(5)\n        assertEquals(\"TRL\", cipher.encode(\"OMG\"))\n    }\n\n    @Ignore\n    @Test\n    fun testSpacesAreUnalteredByRotation() {\n        val cipher = RotationalCipher(5)\n        assertEquals(\"T R L\", cipher.encode(\"O M G\"))\n    }\n\n    @Ignore\n    @Test\n    fun testNumbersAreUnalteredByRotation() {\n        val cipher = RotationalCipher(4)\n        assertEquals(\"Xiwxmrk 1 2 3 xiwxmrk\", cipher.encode(\"Testing 1 2 3 testing\"))\n    }\n\n    @Ignore\n    @Test\n    fun testPunctuationIsUnalteredByRotation() {\n        val cipher = RotationalCipher(21)\n        assertEquals(\"Gzo'n zvo, Bmviyhv!\", cipher.encode(\"Let's eat, Grandma!\"))\n    }\n\n    @Ignore\n    @Test\n    fun testAllLettersRotateCorrectly() {\n        val cipher = RotationalCipher(13)\n        assertEquals(\n                \"Gur dhvpx oebja sbk whzcf bire gur ynml qbt.\",\n                cipher.encode(\"The quick brown fox jumps over the lazy dog.\"))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/run-length-encoding/.docs/instructions.md",
    "content": "# Instructions\n\nImplement run-length encoding and decoding.\n\nRun-length encoding (RLE) is a simple form of data compression, where runs (consecutive data elements) are replaced by just one data value and count.\n\nFor example we can represent the original 53 characters with only 13.\n\n```text\n\"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB\"  ->  \"12WB12W3B24WB\"\n```\n\nRLE allows the original data to be perfectly reconstructed from the compressed data, which makes it a lossless data compression.\n\n```text\n\"AABCCCDEEEE\"  ->  \"2AB3CD4E\"  ->  \"AABCCCDEEEE\"\n```\n\nFor simplicity, you can assume that the unencoded string will only contain the letters A through Z (either lower or upper case) and whitespace.\nThis way data to be encoded will never contain any numbers and numbers inside data to be decoded always represent the count for the following character.\n"
  },
  {
    "path": "exercises/practice/run-length-encoding/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/RunLengthEncoding.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/RunLengthEncodingTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/RunLengthEncoding.kt\"\n    ]\n  },\n  \"blurb\": \"Implement run-length encoding and decoding.\",\n  \"source\": \"Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Run-length_encoding\"\n}\n"
  },
  {
    "path": "exercises/practice/run-length-encoding/.meta/src/reference/kotlin/RunLengthEncoding.kt",
    "content": "import java.util.regex.Pattern\n\nobject RunLengthEncoding {\n\n    private val encodePattern = Pattern.compile(\"\"\"([ a-zA-Z])\\1*\"\"\")\n    private val decodePattern = Pattern.compile(\"\"\"(|\\d+)([ a-zA-Z])\"\"\")\n\n    fun encode(input: String): String {\n        val matcher = encodePattern.matcher(input)\n        val matcherSeq = generateSequence { if (matcher.find()) matcher else null }\n        return matcherSeq.joinToString(\"\") {\n            val characters = it.group(0)\n            val count = if (characters.length == 1) \"\" else characters.length.toString()\n            count + characters.first()\n        }\n    }\n\n    fun decode(input: String): String {\n        val matcher = decodePattern.matcher(input)\n        val matcherSeq = generateSequence { if (matcher.find()) matcher else null }\n        return matcherSeq.joinToString(\"\") {\n            val count = if (it.group(1) == \"\") 1 else it.group(1).toInt()\n            val character = it.group(2)\n            character.repeat(count)\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/run-length-encoding/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# empty string\n\"ad53b61b-6ffc-422f-81a6-61f7df92a231\" = true\n\n# single characters only are encoded without count\n\"52012823-b7e6-4277-893c-5b96d42f82de\" = true\n\n# string with no single characters\n\"b7868492-7e3a-415f-8da3-d88f51f80409\" = true\n\n# single characters mixed with repeated characters\n\"859b822b-6e9f-44d6-9c46-6091ee6ae358\" = true\n\n# multiple whitespace mixed in string\n\"1b34de62-e152-47be-bc88-469746df63b3\" = true\n\n# lowercase characters\n\"abf176e2-3fbd-40ad-bb2f-2dd6d4df721a\" = true\n\n# empty string\n\"7ec5c390-f03c-4acf-ac29-5f65861cdeb5\" = true\n\n# single characters only\n\"ad23f455-1ac2-4b0e-87d0-b85b10696098\" = true\n\n# string with no single characters\n\"21e37583-5a20-4a0e-826c-3dee2c375f54\" = true\n\n# single characters with repeated characters\n\"1389ad09-c3a8-4813-9324-99363fba429c\" = true\n\n# multiple whitespace mixed in string\n\"3f8e3c51-6aca-4670-b86c-a213bf4706b0\" = true\n\n# lower case string\n\"29f721de-9aad-435f-ba37-7662df4fb551\" = true\n\n# encode followed by decode gives original string\n\"2a762efd-8695-4e04-b0d6-9736899fbc16\" = true\n"
  },
  {
    "path": "exercises/practice/run-length-encoding/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/run-length-encoding/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/run-length-encoding/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/run-length-encoding/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/run-length-encoding/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/run-length-encoding/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/run-length-encoding/src/main/kotlin/RunLengthEncoding.kt",
    "content": "object RunLengthEncoding {\n\n    fun encode(input: String): String {\n        TODO(\"Implement this to complete the task\")\n    }\n\n    fun decode(input: String): String {\n        TODO(\"Implement this to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/run-length-encoding/src/test/kotlin/RunLengthEncodingTest.kt",
    "content": "import kotlin.test.Test\nimport kotlin.test.assertEquals\nimport RunLengthEncoding.encode\nimport RunLengthEncoding.decode\nimport kotlin.test.Ignore\n\nclass RunLengthEncodingTest {\n\n    @Test\n    fun `encode_empty string`() = assertEquals(\"\", encode(\"\"))\n\n    @Ignore\n    @Test\n    fun `encode_single characters only are encoded without count`() = assertEquals(\"XYZ\", encode(\"XYZ\"))\n\n    @Ignore\n    @Test\n    fun `encode_string with no single characters`() = assertEquals(\"2A3B4C\", encode(\"AABBBCCCC\"))\n\n    @Ignore\n    @Test\n    fun `encode_single characters mixed with repeated characters`() =\n            assertEquals(\"12WB12W3B24WB\", encode(\"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB\"))\n\n    @Ignore\n    @Test\n    fun `encode_multiple whitespace mixed in string`() = assertEquals(\"2 hs2q q2w2 \", encode(\"  hsqq qww  \"))\n\n    @Ignore\n    @Test\n    fun `encode_lowercase characters`() = assertEquals(\"2a3b4c\", encode(\"aabbbcccc\"))\n\n    @Ignore\n    @Test\n    fun `decode_empty string`() = assertEquals(\"\", decode(\"\"))\n\n    @Ignore\n    @Test\n    fun `decode_single characters only`() = assertEquals(\"XYZ\", decode(\"XYZ\"))\n\n    @Ignore\n    @Test\n    fun `decode_string with no single characters`() = assertEquals(\"AABBBCCCC\", decode(\"2A3B4C\"))\n\n    @Ignore\n    @Test\n    fun `decode_single characters with repeated characters`() =\n            assertEquals(\"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB\", decode(\"12WB12W3B24WB\"))\n\n    @Ignore\n    @Test\n    fun `decode_multiple whitespace mixed in string`() = assertEquals(\"  hsqq qww  \", decode(\"2 hs2q q2w2 \"))\n\n    @Ignore\n    @Test\n    fun `decode_lower case string`() = assertEquals(\"aabbbcccc\", decode(\"2a3b4c\"))\n\n    @Ignore\n    @Test\n    fun `encode followed by decode gives original string`() = assertEquals(\"zzz ZZ  zZ\", decode(encode(\"zzz ZZ  zZ\")))\n\n}\n"
  },
  {
    "path": "exercises/practice/saddle-points/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to find the potential trees where you could build your tree house.\n\nThe data company provides the data as grids that show the heights of the trees.\nThe rows of the grid represent the east-west direction, and the columns represent the north-south direction.\n\nAn acceptable tree will be the largest in its row, while being the smallest in its column.\n\nA grid might not have any good trees at all.\nOr it might have one, or even several.\n\nHere is a grid that has exactly one candidate tree.\n\n```text\n      ↓\n      1  2  3  4\n    |-----------\n  1 | 9  8  7  8\n→ 2 |[5] 3  2  4\n  3 | 6  6  7  1\n```\n\n- Row 2 has values 5, 3, 2, and 4. The largest value is 5.\n- Column 1 has values 9, 5, and 6. The smallest value is 5.\n\nSo the point at `[2, 1]` (row: 2, column: 1) is a great spot for a tree house.\n"
  },
  {
    "path": "exercises/practice/saddle-points/.docs/introduction.md",
    "content": "# Introduction\n\nYou plan to build a tree house in the woods near your house so that you can watch the sun rise and set.\n\nYou've obtained data from a local survey company that show the height of every tree in each rectangular section of the map.\nYou need to analyze each grid on the map to find good trees for your tree house.\n\nA good tree is both:\n\n- taller than every tree to the east and west, so that you have the best possible view of the sunrises and sunsets.\n- shorter than every tree to the north and south, to minimize the amount of tree climbing.\n"
  },
  {
    "path": "exercises/practice/saddle-points/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Matrix.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/MatrixTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Matrix.kt\"\n    ]\n  },\n  \"blurb\": \"Detect saddle points in a matrix.\",\n  \"source\": \"J Dalbey's Programming Practice problems\",\n  \"source_url\": \"https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html\"\n}\n"
  },
  {
    "path": "exercises/practice/saddle-points/.meta/src/reference/kotlin/Matrix.kt",
    "content": "data class Matrix(val entries: List<List<Int>>) {\n\n    val saddlePoints: Set<MatrixCoordinate> by lazy {\n        val result = mutableSetOf<MatrixCoordinate>()\n\n        if (entries.isNotEmpty()) {\n            for (row in entries.indices) {\n                for (col in entries[0].indices) {\n                    val coordinateValue = entries[row][col]\n                    if (coordinateValue == getRowMax(row) && coordinateValue == getColumnMin(col)) {\n                        result.add(MatrixCoordinate(row + 1, col + 1))\n                    }\n                }\n            }\n        }\n\n        result\n    }\n\n    private fun getRowMax(row: Int): Int {\n        return entries[row].maxOrNull() ?: 0\n    }\n\n    private fun getColumnMin(col: Int): Int {\n        return entries\n            .map { row -> row[col] }\n            .minOrNull() ?: 0\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/saddle-points/.meta/src/reference/kotlin/MatrixCoordinate.kt",
    "content": "data class MatrixCoordinate(val row: Int, val col: Int)\n"
  },
  {
    "path": "exercises/practice/saddle-points/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# Can identify single saddle point\n\"3e374e63-a2e0-4530-a39a-d53c560382bd\" = true\n\n# Can identify that empty matrix has no saddle points\n\"6b501e2b-6c1f-491f-b1bb-7f278f760534\" = true\n\n# Can identify lack of saddle points when there are none\n\"8c27cc64-e573-4fcb-a099-f0ae863fb02f\" = true\n\n# Can identify multiple saddle points in a column\n\"6d1399bd-e105-40fd-a2c9-c6609507d7a3\" = true\n\n# Can identify multiple saddle points in a row\n\"3e81dce9-53b3-44e6-bf26-e328885fd5d1\" = true\n\n# Can identify saddle point in bottom right corner\n\"88868621-b6f4-4837-bb8b-3fad8b25d46b\" = true\n\n# Can identify saddle points in a non square matrix\n\"5b9499ca-fcea-4195-830a-9c4584a0ee79\" = true\n\n# Can identify that saddle points in a single column matrix are those with the minimum value\n\"ee99ccd2-a1f1-4283-ad39-f8c70f0cf594\" = true\n\n# Can identify that saddle points in a single row matrix are those with the maximum value\n\"63abf709-a84b-407f-a1b3-456638689713\" = true\n"
  },
  {
    "path": "exercises/practice/saddle-points/.meta/version",
    "content": "1.5.0\n"
  },
  {
    "path": "exercises/practice/saddle-points/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/saddle-points/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/saddle-points/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/saddle-points/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/saddle-points/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/saddle-points/src/main/kotlin/Matrix.kt",
    "content": "data class MatrixCoordinate(val row: Int, val col: Int)\n"
  },
  {
    "path": "exercises/practice/saddle-points/src/test/kotlin/MatrixTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport java.util.Collections.emptySet\nimport kotlin.test.assertEquals\n\nclass MatrixTest {\n\n    @Test\n    fun `single saddle point`() =\n        assertSaddlePointsEqual(\n            Matrix(\n                listOf(\n                    listOf(9, 8, 7),\n                    listOf(5, 3, 2),\n                    listOf(6, 6, 7)\n                )\n            ),\n            setOf(\n                MatrixCoordinate(2, 1)\n            )\n        )\n\n    @Ignore\n    @Test\n    fun `no saddle points for empty matrix`() =\n        assertSaddlePointsEqual(\n            Matrix(listOf(emptyList())),\n            emptySet()\n        )\n\n    @Ignore\n    @Test\n    fun `no saddle points for nonempty matrix`() =\n        assertSaddlePointsEqual(\n            Matrix(\n                listOf(\n                    listOf(1, 2, 3),\n                    listOf(3, 1, 2),\n                    listOf(2, 3, 1)\n                )\n            ),\n            emptySet()\n        )\n\n    @Ignore\n    @Test\n    fun `multiple saddle points in a column`() =\n        assertSaddlePointsEqual(\n            Matrix(\n                listOf(\n                    listOf(4, 5, 4),\n                    listOf(3, 5, 5),\n                    listOf(1, 5, 4)\n                )\n            ),\n            setOf(\n                MatrixCoordinate(1, 2),\n                MatrixCoordinate(2, 2),\n                MatrixCoordinate(3, 2)\n            )\n        )\n\n    @Ignore\n    @Test\n    fun `multiple saddle points in a row`() =\n        assertSaddlePointsEqual(\n            Matrix(\n                listOf(\n                    listOf(6, 7, 8),\n                    listOf(5, 5, 5),\n                    listOf(7, 5, 6)\n                )\n            ),\n            setOf(\n                MatrixCoordinate(2, 1),\n                MatrixCoordinate(2, 2),\n                MatrixCoordinate(2, 3)\n            )\n        )\n\n    @Ignore\n    @Test\n    fun `saddle point in bottom right corner`() =\n        assertSaddlePointsEqual(\n            Matrix(\n                listOf(\n                    listOf(8, 7, 9),\n                    listOf(6, 7, 6),\n                    listOf(3, 2, 5)\n                )\n            ),\n            setOf(\n                MatrixCoordinate(3, 3)\n            )\n        )\n\n    @Ignore\n    @Test\n    fun `saddle points in a single column matrix`() =\n        assertSaddlePointsEqual(\n            Matrix(\n                listOf(\n                    listOf(2),\n                    listOf(1),\n                    listOf(4),\n                    listOf(1)\n                )\n            ),\n            setOf(\n                MatrixCoordinate(2, 1),\n                MatrixCoordinate(4, 1)\n            )\n        )\n\n    @Ignore\n    @Test\n    fun `saddle points in a single row matrix`() =\n        assertSaddlePointsEqual(\n            Matrix(\n                listOf(\n                    listOf(2, 5, 3, 5)\n                )\n            ),\n            setOf(\n                MatrixCoordinate(1, 2),\n                MatrixCoordinate(1, 4)\n            )\n        )\n}\n\nprivate fun assertSaddlePointsEqual(matrix: Matrix, coordinates: Set<MatrixCoordinate>) =\n    assertEquals(coordinates, matrix.saddlePoints)\n\n"
  },
  {
    "path": "exercises/practice/say/.docs/instructions.md",
    "content": "# Instructions\n\nGiven a number from 0 to 999,999,999,999, spell out that number in English.\n\n## Step 1\n\nHandle the basic case of 0 through 99.\n\nIf the input to the program is `22`, then the output should be `'twenty-two'`.\n\nYour program should complain loudly if given a number outside the blessed range.\n\nSome good test cases for this program are:\n\n- 0\n- 14\n- 50\n- 98\n- -1\n- 100\n\n### Extension\n\nIf you're on a Mac, shell out to Mac OS X's `say` program to talk out loud.\nIf you're on Linux or Windows, eSpeakNG may be available with the command `espeak`.\n\n## Step 2\n\nImplement breaking a number up into chunks of thousands.\n\nSo `1234567890` should yield a list like 1, 234, 567, and 890, while the far simpler `1000` should yield just 1 and 0.\n\n## Step 3\n\nNow handle inserting the appropriate scale word between those chunks.\n\nSo `1234567890` should yield `'1 billion 234 million 567 thousand 890'`\n\nThe program must also report any values that are out of range.\nIt's fine to stop at \"trillion\".\n\n## Step 4\n\nPut it all together to get nothing but plain English.\n\n`12345` should give `twelve thousand three hundred forty-five`.\n\nThe program must also report any values that are out of range.\n"
  },
  {
    "path": "exercises/practice/say/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"katrinleinweber\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Say.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/NumberSpellerTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Say.kt\"\n    ]\n  },\n  \"blurb\": \"Given a number from 0 to 999,999,999,999, spell out that number in English.\",\n  \"source\": \"A variation on the JavaRanch CattleDrive, Assignment 4\",\n  \"source_url\": \"https://web.archive.org/web/20240907035912/https://coderanch.com/wiki/718804\"\n}\n"
  },
  {
    "path": "exercises/practice/say/.meta/src/reference/kotlin/Say.kt",
    "content": "class NumberSpeller {\n\n    companion object {\n        val wordMap = mapOf<Long, String>(\n                Pair( 0, \"zero\"     ),\n                Pair( 1, \"one\"      ),\n                Pair( 2, \"two\"      ),\n                Pair( 3, \"three\"    ),\n                Pair( 4, \"four\"     ),\n                Pair( 5, \"five\"     ),\n                Pair( 6, \"six\"      ),\n                Pair( 7, \"seven\"    ),\n                Pair( 8, \"eight\"    ),\n                Pair( 9, \"nine\"     ),\n                Pair(10, \"ten\"      ),\n                Pair(11, \"eleven\"   ),\n                Pair(12, \"twelve\"   ),\n                Pair(13, \"thirteen\" ),\n                Pair(14, \"fourteen\" ),\n                Pair(15, \"fifteen\"  ),\n                Pair(16, \"sixteen\"  ),\n                Pair(17, \"seventeen\"),\n                Pair(18, \"eighteen\" ),\n                Pair(19, \"nineteen\" ),\n                Pair(20, \"twenty\"   ),\n                Pair(30, \"thirty\"   ),\n                Pair(40, \"forty\"    ),\n                Pair(50, \"fifty\"    ),\n                Pair(60, \"sixty\"    ),\n                Pair(70, \"seventy\"  ),\n                Pair(80, \"eighty\"   ),\n                Pair(90, \"ninety\"   )\n        )\n\n        const val te = 10\n        const val hu = 100\n        const val th = 1000\n        const val mi = 1000000\n        const val bi = 1000000000\n        const val tr = 1000000000000\n    }\n\n    fun say(input: Long): String {\n        require(input >= 0) { \"Input must be non-negative\" }\n        require(input < tr)  { \"Input must be less than $tr\" }\n\n        if (input < 20) return wordMap[input]!!\n\n        if (input < hu) {\n            return if (input % te == 0L) {\n                wordMap[input]!!\n            } else {\n                \"${wordMap[input / te * te]}-${wordMap[input % te]!!}\"\n            }\n        }\n\n        if (input < th) {\n            return if (input % hu == 0L) {\n                \"${wordMap[input / hu]!!} hundred\"\n            } else {\n                \"${wordMap[input / hu]!!} hundred ${say(input % hu)}\"\n            }\n        }\n\n        if (input < mi) {\n            return if (input % th == 0L) {\n                \"${say(input / th)} thousand\"\n            } else {\n                \"${say(input / th)} thousand ${say(input % th)}\"\n            }\n        }\n\n        if (input < bi) {\n            return if (input % mi == 0L) {\n                \"${say(input / mi)} million\"\n            } else {\n                \"${say(input / mi)} million ${say(input % mi)}\"\n            }\n        }\n\n        return if (input % bi == 0L) {\n            \"${say(input / bi)} billion\"\n        } else {\n            \"${say(input / bi)} billion ${say(input % bi)}\"\n        }\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/say/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# zero\n\"5d22a120-ba0c-428c-bd25-8682235d83e8\" = true\n\n# one\n\"9b5eed77-dbf6-439d-b920-3f7eb58928f6\" = true\n\n# fourteen\n\"7c499be1-612e-4096-a5e1-43b2f719406d\" = true\n\n# twenty\n\"f541dd8e-f070-4329-92b4-b7ce2fcf06b4\" = true\n\n# twenty-two\n\"d78601eb-4a84-4bfa-bf0e-665aeb8abe94\" = true\n\n# one hundred\n\"e417d452-129e-4056-bd5b-6eb1df334dce\" = true\n\n# one hundred twenty-three\n\"d6924f30-80ba-4597-acf6-ea3f16269da8\" = true\n\n# one thousand\n\"3d83da89-a372-46d3-b10d-de0c792432b3\" = true\n\n# one thousand two hundred thirty-four\n\"865af898-1d5b-495f-8ff0-2f06d3c73709\" = true\n\n# one million\n\"b6a3f442-266e-47a3-835d-7f8a35f6cf7f\" = true\n\n# one million two thousand three hundred forty-five\n\"2cea9303-e77e-4212-b8ff-c39f1978fc70\" = true\n\n# one billion\n\"3e240eeb-f564-4b80-9421-db123f66a38f\" = true\n\n# a big number\n\"9a43fed1-c875-4710-8286-5065d73b8a9e\" = true\n\n# numbers below zero are out of range\n\"49a6a17b-084e-423e-994d-a87c0ecc05ef\" = true\n\n# numbers above 999,999,999,999 are out of range\n\"4d6492eb-5853-4d16-9d34-b0f61b261fd9\" = true\n"
  },
  {
    "path": "exercises/practice/say/.meta/version",
    "content": "1.2.0\n"
  },
  {
    "path": "exercises/practice/say/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/say/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/say/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/say/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/say/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/say/src/main/kotlin/Say.kt",
    "content": "class NumberSpeller {\n\n    fun say(input: Long): String {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/say/src/test/kotlin/NumberSpellerTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport java.lang.IllegalArgumentException\nimport kotlin.test.assertEquals\n\nclass NumberSpellerTest {\n    @Test\n    fun `0 as zero`() = 0.shouldSoundLike(\"zero\")\n\n    @Ignore\n    @Test\n    fun `1 as one`() = 1.shouldSoundLike(\"one\")\n\n    @Ignore\n    @Test\n    fun `14 as fourteen`() = 14.shouldSoundLike(\"fourteen\")\n\n    @Ignore\n    @Test\n    fun `20 as twenty`() = 20.shouldSoundLike(\"twenty\")\n\n    @Ignore\n    @Test\n    fun `22 as twenty-two`() = 22.shouldSoundLike(\"twenty-two\")\n\n    @Ignore\n    @Test\n    fun `100 as one hundred`() = 100.shouldSoundLike(\"one hundred\")\n\n    @Ignore\n    @Test\n    fun `123 as one hundred twenty-three`() = 123.shouldSoundLike(\"one hundred twenty-three\")\n\n    @Ignore\n    @Test\n    fun `1000 as one thousand`() = 1000.shouldSoundLike(\"one thousand\")\n\n    @Ignore\n    @Test\n    fun `1234 as one thousand two hundred thirty-four`() = 1234.shouldSoundLike(\"one thousand two hundred thirty-four\")\n\n    @Ignore\n    @Test\n    fun `1000000 as one million`() = 1000000.shouldSoundLike(\"one million\")\n\n    @Ignore\n    @Test\n    fun `1002345 as one million two thousand three hundred forty-five`() =\n        1002345.shouldSoundLike(\"one million two thousand three hundred forty-five\")\n\n    @Ignore\n    @Test\n    fun `1000000000 as one billion`() = 1000000000.shouldSoundLike(\"one billion\")\n\n    @Ignore\n    @Test\n    fun `spell a big number`() = 987654321123\n        .shouldSoundLike(\"nine hundred eighty-seven billion six hundred fifty-four million three hundred twenty-one thousand one hundred twenty-three\")\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `numbers below zero are out of range`() {\n        NumberSpeller().say(-1)\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `numbers above 999,999,999,999 are out of range`() {\n        NumberSpeller().say(1000000000000)\n    }\n}\n\nprivate fun Long.shouldSoundLike(expected: String) = assertEquals(expected, NumberSpeller().say(this))\n\nprivate fun Int.shouldSoundLike(expected: String) = this.toLong().shouldSoundLike(expected)\n"
  },
  {
    "path": "exercises/practice/scale-generator/.docs/instructions.md",
    "content": "# Instructions\n\n## Chromatic Scales\n\nScales in Western music are based on the chromatic (12-note) scale.\nThis scale can be expressed as the following group of pitches:\n\n> A, A♯, B, C, C♯, D, D♯, E, F, F♯, G, G♯\n\nA given sharp note (indicated by a ♯) can also be expressed as the flat of the note above it (indicated by a ♭) so the chromatic scale can also be written like this:\n\n> A, B♭, B, C, D♭, D, E♭, E, F, G♭, G, A♭\n\nThe major and minor scale and modes are subsets of this twelve-pitch collection.\nThey have seven pitches, and are called diatonic scales.\nThe collection of notes in these scales is written with either sharps or flats, depending on the tonic (starting note).\nHere is a table indicating whether the flat expression or sharp expression of the scale would be used for a given tonic:\n\n| Key Signature | Major                 | Minor                |\n| ------------- | --------------------- | -------------------- |\n| Natural       | C                     | a                    |\n| Sharp         | G, D, A, E, B, F♯     | e, b, f♯, c♯, g♯, d♯ |\n| Flat          | F, B♭, E♭, A♭, D♭, G♭ | d, g, c, f, b♭, e♭   |\n\nNote that by common music theory convention the natural notes \"C\" and \"a\" follow the sharps scale when ascending and the flats scale when descending.\nFor the scope of this exercise the scale is only ascending.\n\n### Task\n\nGiven a tonic, generate the 12 note chromatic scale starting with the tonic.\n\n- Shift the base scale appropriately so that all 12 notes are returned starting with the given tonic.\n- For the given tonic, determine if the scale is to be returned with flats or sharps.\n- Return all notes in uppercase letters (except for the `b` for flats) irrespective of the casing of the given tonic.\n\n## Diatonic Scales\n\nThe diatonic scales, and all other scales that derive from the chromatic scale, are built upon intervals.\nAn interval is the space between two pitches.\n\nThe simplest interval is between two adjacent notes, and is called a \"half step\", or \"minor second\" (sometimes written as a lower-case \"m\").\nThe interval between two notes that have an interceding note is called a \"whole step\" or \"major second\" (written as an upper-case \"M\").\nThe diatonic scales are built using only these two intervals between adjacent notes.\n\nNon-diatonic scales can contain other intervals.\nAn \"augmented second\" interval, written \"A\", has two interceding notes (e.g., from A to C or D♭ to E) or a \"whole step\" plus a \"half step\".\nThere are also smaller and larger intervals, but they will not figure into this exercise.\n\n### Task\n\nGiven a tonic and a set of intervals, generate the musical scale starting with the tonic and following the specified interval pattern.\n\nThis is similar to generating chromatic scales except that instead of returning 12 notes, you will return N+1 notes for N intervals.\nThe first note is always the given tonic.\nThen, for each interval in the pattern, the next note is determined by starting from the previous note and skipping the number of notes indicated by the interval.\n\nFor example, starting with G and using the seven intervals MMmMMMm, there would be the following eight notes:\n\n| Note | Reason                                            |\n| ---- | ------------------------------------------------- |\n| G    | Tonic                                             |\n| A    | M indicates a whole step from G, skipping G♯      |\n| B    | M indicates a whole step from A, skipping A♯      |\n| C    | m indicates a half step from B, skipping nothing  |\n| D    | M indicates a whole step from C, skipping C♯      |\n| E    | M indicates a whole step from D, skipping D♯      |\n| F♯   | M indicates a whole step from E, skipping F       |\n| G    | m indicates a half step from F♯, skipping nothing |\n"
  },
  {
    "path": "exercises/practice/scale-generator/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"jmrunkle\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Scale.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ScaleTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Scale.kt\"\n    ]\n  },\n  \"blurb\": \"Generate musical scales, given a starting note and a set of intervals.\"\n}\n"
  },
  {
    "path": "exercises/practice/scale-generator/.meta/src/reference/kotlin/Scale.kt",
    "content": "class Scale(private val tonic: String) {\n\n    companion object {\n        private val sharps = listOf(\"A\", \"A#\", \"B\", \"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\")\n        private val flats = listOf(\"A\", \"Bb\", \"B\", \"C\", \"Db\", \"D\", \"Eb\", \"E\", \"F\", \"Gb\", \"G\", \"Ab\")\n        private val useFlats = listOf(\"F\", \"Bb\", \"Eb\", \"Ab\", \"Db\", \"Gb\", \"d\", \"g\", \"c\", \"f\", \"bb\", \"eb\")\n        private val intervalOffsets = mapOf('m' to 1, 'M' to 2, 'A' to 3)\n    }\n\n    private val orderedChromatic: List<String>\n\n    init {\n        val notes = if (useFlats.contains(tonic)) flats else sharps\n        val start = notes.indexOfFirst { it.lowercase() == tonic.lowercase() }\n        orderedChromatic = notes.subList(start, notes.size) + notes.subList(0, start)\n    }\n\n    fun chromatic(): List<String> = orderedChromatic\n\n    fun interval(intervals: String): List<String> {\n        var idx = 0\n        return intervals.map {\n            val note = orderedChromatic[idx]\n            idx += intervalOffsets[it] ?: error(\"Unkown interval $it!\")\n            note\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/scale-generator/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# Chromatic scale with sharps\n\"10ea7b14-8a49-40be-ac55-7c62b55f9b47\" = true\n\n# Chromatic scale with flats\n\"af8381de-9a72-4efd-823a-48374dbfe76f\" = true\n\n# Simple major scale\n\"6f5b1410-1dd7-4c6c-b410-6b7e986f6f1e\" = true\n\n# Major scale with sharps\n\"13a92f89-a83e-40b5-b9d4-01136931ba02\" = true\n\n# Major scale with flats\n\"aa3320f6-a761-49a1-bcf6-978e0c81080a\" = true\n\n# Minor scale with sharps\n\"63daeb2f-c3f9-4c45-92be-5bf97f61ff94\" = true\n\n# Minor scale with flats\n\"616594d0-9c48-4301-949e-af1d4fad16fd\" = true\n\n# Dorian mode\n\"390bd12c-5ac7-4ec7-bdde-4e58d5c78b0a\" = true\n\n# Mixolydian mode\n\"846d0862-0f3e-4f3b-8a2d-9cc74f017848\" = true\n\n# Lydian mode\n\"7d49a8bb-b5f7-46ad-a207-83bd5032291a\" = true\n\n# Phrygian mode\n\"a4e4dac5-1891-4160-a19f-bb06d653d4d0\" = true\n\n# Locrian mode\n\"ef3650af-90f8-4ad9-9ef6-fdbeae07dcaa\" = true\n\n# Harmonic minor\n\"70517400-12b7-4530-b861-fa940ae69ee8\" = true\n\n# Octatonic\n\"37114c0b-c54d-45da-9f4b-3848201470b0\" = true\n\n# Hexatonic\n\"496466e7-aa45-4bbd-a64d-f41030feed9c\" = true\n\n# Pentatonic\n\"bee5d9ec-e226-47b6-b62b-847a9241f3cc\" = true\n\n# Enigmatic\n\"dbee06a6-7535-4ab7-98e8-d8a36c8402d1\" = true\n"
  },
  {
    "path": "exercises/practice/scale-generator/.meta/version",
    "content": "2.0.0\n"
  },
  {
    "path": "exercises/practice/scale-generator/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/scale-generator/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/scale-generator/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/scale-generator/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/scale-generator/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/scale-generator/src/main/kotlin/Scale.kt",
    "content": "class Scale(private val tonic: String) {\n\n    fun chromatic(): List<String> {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun interval(intervals: String): List<String> {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/scale-generator/src/test/kotlin/ScaleTest.kt",
    "content": "import kotlin.test.Ignore\nimport kotlin.test.asserter\nimport kotlin.test.Test\n\nclass ScaleTest {\n\n    // Test chromatic scales\n    @Test\n    fun `chromatic scale with sharps`() {\n        val expected = listOf(\"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\", \"A\", \"A#\", \"B\")\n        assertScalesEqual(expected, Scale(\"C\").chromatic())\n    }\n\n    @Ignore\n    @Test\n    fun `chromatic scale with flats`() {\n        val expected = listOf(\"F\", \"Gb\", \"G\", \"Ab\", \"A\", \"Bb\", \"B\", \"C\", \"Db\", \"D\", \"Eb\", \"E\")\n        assertScalesEqual(expected, Scale(\"F\").chromatic())\n    }\n\n    // Test scales with specified intervals\n    @Ignore\n    @Test\n    fun `simple major scale`() {\n        val expected = listOf(\"C\", \"D\", \"E\", \"F\", \"G\", \"A\", \"B\")\n        assertScalesEqual(expected, Scale(\"C\").interval(\"MMmMMMm\"))\n    }\n\n    @Ignore\n    @Test\n    fun `major scale with sharps`() {\n        val expected = listOf(\"G\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F#\")\n        assertScalesEqual(expected, Scale(\"G\").interval(\"MMmMMMm\"))\n    }\n\n    @Ignore\n    @Test\n    fun `major scale with flats`() {\n        val expected = listOf(\"F\", \"G\", \"A\", \"Bb\", \"C\", \"D\", \"E\")\n        assertScalesEqual(expected, Scale(\"F\").interval(\"MMmMMMm\"))\n    }\n\n    @Ignore\n    @Test\n    fun `minor scale with sharps`() {\n        val expected = listOf(\"F#\", \"G#\", \"A\", \"B\", \"C#\", \"D\", \"E\")\n        assertScalesEqual(expected, Scale(\"f#\").interval(\"MmMMmMM\"))\n    }\n\n    @Ignore\n    @Test\n    fun `minor scale with flats`() {\n        val expected = listOf(\"Bb\", \"C\", \"Db\", \"Eb\", \"F\", \"Gb\", \"Ab\")\n        assertScalesEqual(expected, Scale(\"bb\").interval(\"MmMMmMM\"))\n    }\n\n    @Ignore\n    @Test\n    fun `dorian mode`() {\n        val expected = listOf(\"D\", \"E\", \"F\", \"G\", \"A\", \"B\", \"C\")\n        assertScalesEqual(expected, Scale(\"d\").interval(\"MmMMMmM\"))\n    }\n\n    @Ignore\n    @Test\n    fun `mixolydian mode`() {\n        val expected = listOf(\"Eb\", \"F\", \"G\", \"Ab\", \"Bb\", \"C\", \"Db\")\n        assertScalesEqual(expected, Scale(\"Eb\").interval(\"MMmMMmM\"))\n    }\n\n    @Ignore\n    @Test\n    fun `lydian mode`() {\n        val expected = listOf(\"A\", \"B\", \"C#\", \"D#\", \"E\", \"F#\", \"G#\")\n        assertScalesEqual(expected, Scale(\"a\").interval(\"MMMmMMm\"))\n    }\n\n    @Ignore\n    @Test\n    fun `phrygian mode`() {\n        val expected = listOf(\"E\", \"F\", \"G\", \"A\", \"B\", \"C\", \"D\")\n        assertScalesEqual(expected, Scale(\"e\").interval(\"mMMMmMM\"))\n    }\n\n    @Ignore\n    @Test\n    fun `locrian mode`() {\n        val expected = listOf(\"G\", \"Ab\", \"Bb\", \"C\", \"Db\", \"Eb\", \"F\")\n        assertScalesEqual(expected, Scale(\"g\").interval(\"mMMmMMM\"))\n    }\n\n    @Ignore\n    @Test\n    fun `harmonic minor`() {\n        val expected = listOf(\"D\", \"E\", \"F\", \"G\", \"A\", \"Bb\", \"Db\")\n        assertScalesEqual(expected, Scale(\"d\").interval(\"MmMMmAm\"))\n    }\n\n    @Ignore\n    @Test\n    fun octatonic() {\n        val expected = listOf(\"C\", \"D\", \"D#\", \"F\", \"F#\", \"G#\", \"A\", \"B\")\n        assertScalesEqual(expected, Scale(\"C\").interval(\"MmMmMmMm\"))\n    }\n\n    @Ignore\n    @Test\n    fun hexatonic() {\n        val expected = listOf(\"Db\", \"Eb\", \"F\", \"G\", \"A\", \"B\")\n        assertScalesEqual(expected, Scale(\"Db\").interval(\"MMMMMM\"))\n    }\n\n    @Ignore\n    @Test\n    fun pentatonic() {\n        val expected = listOf(\"A\", \"B\", \"C#\", \"E\", \"F#\")\n        assertScalesEqual(expected, Scale(\"A\").interval(\"MMAMA\"))\n    }\n\n    @Ignore\n    @Test\n    fun enigmatic() {\n        val expected = listOf(\"G\", \"G#\", \"B\", \"C#\", \"D#\", \"F\", \"F#\")\n        assertScalesEqual(expected, Scale(\"G\").interval(\"mAMMMmm\"))\n    }\n\n    private fun assertScalesEqual(expected: List<String>, actual: List<String>) {\n        asserter.assertTrue(\n            { \"Scales should be equal. Expected <$expected>, actual <$actual>\" },\n            scalesAreEqual(expected, actual))\n    }\n\n    private fun scalesAreEqual(expected: List<String>, actual: List<String>): Boolean {\n        if (expected.size != actual.size) return false\n        return expected.zip(actual, this::notesEqual).all { it }\n    }\n\n    // Few enough equal notes that we can just list them all\n    fun notesEqual(left: String, right: String) = left == right || when(left) {\n        // A# == Bb\n        \"A#\" -> right == \"Bb\"\n        \"Bb\" -> right == \"A#\"\n        // C# == Db\n        \"C#\" -> right == \"Db\"\n        \"Db\" -> right == \"C#\"\n        // D# == Eb\n        \"D#\" -> right == \"Eb\"\n        \"Eb\" -> right == \"D#\"\n        // F# == Gb\n        \"F#\" -> right == \"Gb\"\n        \"Gb\" -> right == \"F#\"\n        // G# == Ab\n        \"G#\" -> right == \"Ab\"\n        \"Ab\" -> right == \"G#\"\n        else -> false\n    }\n}\n"
  },
  {
    "path": "exercises/practice/scrabble-score/.approaches/config.json",
    "content": "{\n  \"introduction\": {\n    \"authors\": [\n      \"bobahop\"\n    ]\n  },\n  \"approaches\": [\n    {\n      \"uuid\": \"02863caf-f7d0-45bd-87f8-408e0030be55\",\n      \"slug\": \"map\",\n      \"title\": \"map\",\n      \"blurb\": \"Use map lookups to return the answer.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    },\n    {\n      \"uuid\": \"5481eb78-3c12-458f-b88c-3cf7632856e1\",\n      \"slug\": \"when\",\n      \"title\": \"when\",\n      \"blurb\": \"Use when lookups to return the answer.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "exercises/practice/scrabble-score/.approaches/introduction.md",
    "content": "# Introduction\n\nThere are several ways to solve Scrabble Score.\nOne approach is to use a [`when`][when] expression for looking up the letter scores.\nAnother approach is to use a [`Map`][map] for looking up the letter scores.\n\n## Approach: `when`\n\n```kotlin\nobject ScrabbleScore {\n\n    private fun scoreLetter(c: Char) =\n            when (c.uppercaseChar()) {\n                'A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T' -> 1\n                'D', 'G' -> 2\n                'B', 'C', 'M', 'P' -> 3\n                'F', 'H', 'V', 'W', 'Y' -> 4\n                'K' -> 5\n                'J', 'X' -> 8\n                'Q', 'Z' -> 10\n                else -> 0\n            }\n\n    fun scoreWord(word: String) = word.sumOf { scoreLetter(it) }\n}\n```\n\nFor more information, check the [`when` approach][approach-when].\n\n## Approach: `Map`\n\n```kotlin\nobject ScrabbleScore {\n    private val compressedMap =\n            mapOf(\n                    1 to listOf('A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'),\n                    2 to listOf('D', 'G'),\n                    3 to listOf('B', 'C', 'M', 'P'),\n                    4 to listOf('F', 'H', 'V', 'W', 'Y'),\n                    5 to listOf('K'),\n                    8 to listOf('J', 'X'),\n                    10 to listOf('Q', 'Z')\n            )\n    private val lookup = mutableMapOf<Char, Int>()\n\n    init {\n        compressedMap.forEach { entry ->\n            entry.value.forEach { letter -> lookup.put(letter, entry.key) }\n        }\n    }\n\n    fun scoreWord(word: String) = word.sumOf { lookup.getValue(it.uppercaseChar()) }\n}\n```\n\nFor more information, check the [`Map` approach][approach-map].\n\n## Which approach to use?\n\nThe `when` approach is succinct and reasonably performant.\nA `Map` lookup is fast, but it takes time to set up a `Map`, so for only a few lookups a `when` may be finished before the `Map` is built.\nOnce the `Map` is built, if there are a lot of lookups, then the `Map` may finish all of them sooner than a `when`.\n\n[approach-when]: https://exercism.org/tracks/kotlin/exercises/scrabble-score/approaches/when\n[approach-map]: https://exercism.org/tracks/kotlin/exercises/scrabble-score/approaches/map\n[when]: https://kotlinlang.org/docs/control-flow.html#when-expression\n[map]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/\n"
  },
  {
    "path": "exercises/practice/scrabble-score/.approaches/map/content.md",
    "content": "# `Map`\n\n```kotlin\nobject ScrabbleScore {\n    private val compressedMap =\n            mapOf(\n                    1 to listOf('A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'),\n                    2 to listOf('D', 'G'),\n                    3 to listOf('B', 'C', 'M', 'P'),\n                    4 to listOf('F', 'H', 'V', 'W', 'Y'),\n                    5 to listOf('K'),\n                    8 to listOf('J', 'X'),\n                    10 to listOf('Q', 'Z')\n            )\n    private val lookup = mutableMapOf<Char, Int>()\n\n    init {\n        compressedMap.forEach { entry ->\n            entry.value.forEach { letter -> lookup.put(letter, entry.key) }\n        }\n    }\n\n    fun scoreWord(word: String) = word.sumOf { lookup.getValue(it.uppercaseChar()) }\n}\n```\n\nAn [object declaration][object] is used to define `ScrabbleScore` as essentially a [singleton][singleton] object instantiation of the class.\nThis is sufficient, since there is no object state that needs to change with each call of the `scoreWord` method.\n\nA [`private`][visibility] [`val`][variables] is defined to hold a `Map`.\nThe `Map` is constructed with the [`mapOf`][mapOf] method, which is passed key/value [pairs][pair] made by the [`to`][to] keyword\nto associate the score key with its list of `Char` values.\nThis is less tedious then typing the `Map` with a letter key and its score value for all of the letters.\n\nHowever, for an efficient lookup, we _want_ a letter key with its score value, so the [`mutableMapOf`][mutableMapOf] method is used\nto initialize the lookup map.\n\nInside an [initializer block][constructors], two `forEach` loops are used for loading the lookup `Map` with the transformed key/values from the first `Map`.\n(If you have solved the `Etl` exercise, then this will be familiar to you.)\nEach key/value entry is passed into the [lambda][lambda] for the outer `forEach`.\nThe inner `forEach` is called on the list of `Char` values for the entry.\nEach `Char` letter is passed into the lambda for the inner `forEach`, where the `put` method is used to create a new entry in the lookup `Map`,\nwith the letter as the key and the score as the value.\n\nThe `scoreWord` function is also a single-expression function, implemented with the `sumOf` [aggregate operation][aggregate-operation] on the input word.\nThe [lambda][lambda] of `sumOf` uses the [`it`][it] keyword to refer to the single `Char` parameter for the lambda, and passes that to the\n[`getValue`][getvalue] method of the `Map` to look up the score for the letter.\nThe function returns the result of calling `sumOf`, which is the sum of the scores for each of the characters in the word.\n\n[object]: https://kotlinlang.org/docs/object-declarations.html#object-declarations-overview\n[singleton]: https://en.wikipedia.org/wiki/Singleton_pattern\n[visibility]: https://kotlinlang.org/docs/visibility-modifiers.html\n[variables]: https://kotlinlang.org/docs/basic-syntax.html#variables\n[mapOf]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map-of.html\n[pair]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-pair/\n[to]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/to.html\n[mutableMapOf]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-map-of.html\n[constructors]: https://kotlinlang.org/docs/classes.html#constructors\n[single-expression-function]: https://kotlinlang.org/docs/functions.html#single-expression-functions\n[type-inference]: https://kotlinlang.org/spec/type-inference.html\n[aggregate-operation]: https://kotlinlang.org/docs/collection-aggregate.html\n[lambda]: https://kotlinlang.org/docs/lambdas.html#lambda-expressions-and-anonymous-functions\n[it]: https://kotlinlang.org/docs/lambdas.html#it-implicit-name-of-a-single-parameter\n[getvalue]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/get-value.html\n"
  },
  {
    "path": "exercises/practice/scrabble-score/.approaches/map/snippet.txt",
    "content": "private val compressedMap =\n    mapOf(\n            1 to listOf('A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'),\n            2 to listOf('D', 'G'),\n            3 to listOf('B', 'C', 'M', 'P'),\n            4 to listOf('F', 'H', 'V', 'W', 'Y'),\n            5 to listOf('K'),\n            8 to listOf('J', 'X'),\n"
  },
  {
    "path": "exercises/practice/scrabble-score/.approaches/when/content.md",
    "content": "# `when`\n\n```kotlin\nobject ScrabbleScore {\n\n    private fun scoreLetter(c: Char) =\n            when (c.uppercaseChar()) {\n                'A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T' -> 1\n                'D', 'G' -> 2\n                'B', 'C', 'M', 'P' -> 3\n                'F', 'H', 'V', 'W', 'Y' -> 4\n                'K' -> 5\n                'J', 'X' -> 8\n                'Q', 'Z' -> 10\n                else -> 0\n            }\n\n    fun scoreWord(word: String) = word.sumOf { scoreLetter(it) }\n}\n```\n\nAn [object declaration][object] is used to define `ScrabbleScore` as essentially a [singleton][singleton] object instantiation of the class.\nThis is sufficient, since there is no object state that needs to change with each call of the `scoreWord` method.\n\nThe [`private`][visibility] method for scoring the letter is implemented by a [`when`][when] expression.\nAlthough the function has multiple lines, it consists only of the one `when` expression, so it is defined using\n[single-expression function][single-expression-function] syntax, with the curly braces omitted and the return type [inferred][type-inference].\n\nThe `scoreWord` function is also a single-expression function, implemented with the `sumOf` [aggregate operation][aggregate-operation] on the input word.\nThe [lambda][lambda] of `sumOf` uses the [`it`][it] keyword to refer to the single `Char` parameter for the lambda, and passes that to the function\nfor scoring a letter.\nThe function returns the result of calling `sumOf`, which is the sum of the scores for each of the characters in the word.\n\n[object]: https://kotlinlang.org/docs/object-declarations.html#object-declarations-overview\n[singleton]: https://en.wikipedia.org/wiki/Singleton_pattern\n[visibility]: https://kotlinlang.org/docs/visibility-modifiers.html\n[when]: https://kotlinlang.org/docs/control-flow.html#when-expression\n[single-expression-function]: https://kotlinlang.org/docs/functions.html#single-expression-functions\n[type-inference]: https://kotlinlang.org/spec/type-inference.html\n[aggregate-operation]: https://kotlinlang.org/docs/collection-aggregate.html\n[lambda]: https://kotlinlang.org/docs/lambdas.html#lambda-expressions-and-anonymous-functions\n[it]: https://kotlinlang.org/docs/lambdas.html#it-implicit-name-of-a-single-parameter\n"
  },
  {
    "path": "exercises/practice/scrabble-score/.approaches/when/snippet.txt",
    "content": "private fun scoreLetter(c: Char) =\n    when (c.uppercaseChar()) {\n        'A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T' -> 1\n        'D', 'G' -> 2\n        'B', 'C', 'M', 'P' -> 3\n        'F', 'H', 'V', 'W', 'Y' -> 4\n        'K' -> 5\n        'J', 'X' -> 8\n"
  },
  {
    "path": "exercises/practice/scrabble-score/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to compute a word's Scrabble score by summing the values of its letters.\n\nThe letters are valued as follows:\n\n| Letter                       | Value |\n| ---------------------------- | ----- |\n| A, E, I, O, U, L, N, R, S, T | 1     |\n| D, G                         | 2     |\n| B, C, M, P                   | 3     |\n| F, H, V, W, Y                | 4     |\n| K                            | 5     |\n| J, X                         | 8     |\n| Q, Z                         | 10    |\n\nFor example, the word \"cabbage\" is worth 14 points:\n\n- 3 points for C\n- 1 point for A\n- 3 points for B\n- 3 points for B\n- 1 point for A\n- 2 points for G\n- 1 point for E\n"
  },
  {
    "path": "exercises/practice/scrabble-score/.docs/introduction.md",
    "content": "# Introduction\n\n[Scrabble][wikipedia] is a word game where players place letter tiles on a board to form words.\nEach letter has a value.\nA word's score is the sum of its letters' values.\n\n[wikipedia]: https://en.wikipedia.org/wiki/Scrabble\n"
  },
  {
    "path": "exercises/practice/scrabble-score/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/ScrabbleScore.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ScrabbleScoreTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/ScrabbleScore.kt\"\n    ]\n  },\n  \"blurb\": \"Given a word, compute the Scrabble score for that word.\",\n  \"source\": \"Inspired by the Extreme Startup game\",\n  \"source_url\": \"https://github.com/rchatley/extreme_startup\"\n}\n"
  },
  {
    "path": "exercises/practice/scrabble-score/.meta/src/reference/kotlin/ScrabbleScore.kt",
    "content": "object ScrabbleScore {\n    private val scoreToLetters = mapOf(1 to \"AEIOULNRST\", 2 to \"DG\", 3 to \"BCMP\", 4 to \"FHVWY\", 5 to \"K\", 8 to \"JX\", 10 to \"QZ\").mapValues { it.value.toCharArray() }\n    private val letterToScore = scoreToLetters.flatMap { entry -> entry.value.map { char -> Pair(char, entry.key) } }.toMap()\n\n    fun scoreLetter(c: Char) = letterToScore[c.uppercaseChar()] ?: 0\n    fun scoreWord(word: String) = word.fold(0) { score, char -> score + scoreLetter(char) }\n}\n"
  },
  {
    "path": "exercises/practice/scrabble-score/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# lowercase letter\n\"f46cda29-1ca5-4ef2-bd45-388a767e3db2\" = true\n\n# uppercase letter\n\"f7794b49-f13e-45d1-a933-4e48459b2201\" = true\n\n# valuable letter\n\"eaba9c76-f9fa-49c9-a1b0-d1ba3a5b31fa\" = true\n\n# short word\n\"f3c8c94e-bb48-4da2-b09f-e832e103151e\" = true\n\n# short, valuable word\n\"71e3d8fa-900d-4548-930e-68e7067c4615\" = true\n\n# medium word\n\"d3088ad9-570c-4b51-8764-c75d5a430e99\" = true\n\n# medium, valuable word\n\"fa20c572-ad86-400a-8511-64512daac352\" = true\n\n# long, mixed-case word\n\"9336f0ba-9c2b-4fa0-bd1c-2e2d328cf967\" = true\n\n# english-like word\n\"1e34e2c3-e444-4ea7-b598-3c2b46fd2c10\" = true\n\n# empty input\n\"4efe3169-b3b6-4334-8bae-ff4ef24a7e4f\" = true\n\n# entire alphabet available\n\"3b305c1c-f260-4e15-a5b5-cb7d3ea7c3d7\" = true\n"
  },
  {
    "path": "exercises/practice/scrabble-score/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/scrabble-score/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/scrabble-score/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/scrabble-score/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/scrabble-score/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/scrabble-score/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/scrabble-score/src/main/kotlin/ScrabbleScore.kt",
    "content": "object ScrabbleScore {\n\n    fun scoreLetter(c: Char): Int {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun scoreWord(word: String): Int {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/scrabble-score/src/test/kotlin/ScrabbleScoreTest.kt",
    "content": "import org.junit.Test\nimport org.junit.runner.RunWith\nimport org.junit.runners.Parameterized\nimport kotlin.test.assertEquals\n\n@RunWith(Parameterized::class)\nclass ScrabbleScoreTest(val input: String, val expectedOutput: Int) {\n\n    companion object {\n        @JvmStatic\n        @Parameterized.Parameters(name = \"{index}: scoreWord({0})={1}\")\n        fun data() = listOf(\n                arrayOf(\"a\", 1),\n                arrayOf(\"A\", 1),\n                arrayOf(\"f\", 4),\n                arrayOf(\"at\", 2),\n                arrayOf(\"zoo\", 12),\n                arrayOf(\"street\", 6),\n                arrayOf(\"quirky\", 22),\n                arrayOf(\"OxyphenButazone\", 41),\n                arrayOf(\"pinata\", 8),\n                arrayOf(\"\", 0),\n                arrayOf(\"abcdefghijklmnopqrstuvwxyz\", 87)\n        )\n    }\n\n    @Test\n    fun test() {\n        assertEquals(expectedOutput, ScrabbleScore.scoreWord(input))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/secret-handshake/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to convert a number between 1 and 31 to a sequence of actions in the secret handshake.\n\nThe sequence of actions is chosen by looking at the rightmost five digits of the number once it's been converted to binary.\nStart at the right-most digit and move left.\n\nThe actions for each number place are:\n\n```plaintext\n00001 = wink\n00010 = double blink\n00100 = close your eyes\n01000 = jump\n10000 = Reverse the order of the operations in the secret handshake.\n```\n\nLet's use the number `9` as an example:\n\n- 9 in binary is `1001`.\n- The digit that is farthest to the right is 1, so the first action is `wink`.\n- Going left, the next digit is 0, so there is no double-blink.\n- Going left again, the next digit is 0, so you leave your eyes open.\n- Going left again, the next digit is 1, so you jump.\n\nThat was the last digit, so the final code is:\n\n```plaintext\nwink, jump\n```\n\nGiven the number 26, which is `11010` in binary, we get the following actions:\n\n- double blink\n- jump\n- reverse actions\n\nThe secret handshake for 26 is therefore:\n\n```plaintext\njump, double blink\n```\n\n~~~~exercism/note\nIf you aren't sure what binary is or how it works, check out [this binary tutorial][intro-to-binary].\n\n[intro-to-binary]: https://medium.com/basecs/bits-bytes-building-with-binary-13cb4289aafa\n~~~~\n"
  },
  {
    "path": "exercises/practice/secret-handshake/.docs/introduction.md",
    "content": "# Introduction\n\nYou are starting a secret coding club with some friends and friends-of-friends.\nNot everyone knows each other, so you and your friends have decided to create a secret handshake that you can use to recognize that someone is a member.\nYou don't want anyone who isn't in the know to be able to crack the code.\n\nYou've designed the code so that one person says a number between 1 and 31, and the other person turns it into a series of actions.\n"
  },
  {
    "path": "exercises/practice/secret-handshake/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/HandshakeCalculator.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/HandshakeCalculatorTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/HandshakeCalculator.kt\"\n    ]\n  },\n  \"blurb\": \"Given a decimal number, convert it to the appropriate sequence of events for a secret handshake.\",\n  \"source\": \"Bert, in Mary Poppins\",\n  \"source_url\": \"https://www.imdb.com/title/tt0058331/quotes/?item=qt0437047\"\n}\n"
  },
  {
    "path": "exercises/practice/secret-handshake/.meta/src/reference/kotlin/HandshakeCalculator.kt",
    "content": "object HandshakeCalculator {\n\n    private const val REVERSE_SIGNALS_BIT_POSITION = 4\n\n    fun calculateHandshake(number: Int): List<Signal> {\n        val result = Signal.values().filter {\n            signal -> isBitSet(signal.ordinal, number)\n        }\n\n        if (isBitSet(REVERSE_SIGNALS_BIT_POSITION, number)) {\n            return result.asReversed()\n        } else {\n            return result\n        }\n    }\n\n    private fun isBitSet(position: Int, number: Int): Boolean {\n        return number shr position and 1 == 1\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/secret-handshake/.meta/src/reference/kotlin/Signal.kt",
    "content": "enum class Signal {\n\n  WINK, DOUBLE_BLINK, CLOSE_YOUR_EYES, JUMP\n\n}\n"
  },
  {
    "path": "exercises/practice/secret-handshake/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# wink for 1\n\"b8496fbd-6778-468c-8054-648d03c4bb23\" = true\n\n# double blink for 10\n\"83ec6c58-81a9-4fd1-bfaf-0160514fc0e3\" = true\n\n# close your eyes for 100\n\"0e20e466-3519-4134-8082-5639d85fef71\" = true\n\n# jump for 1000\n\"b339ddbb-88b7-4b7d-9b19-4134030d9ac0\" = true\n\n# combine two actions\n\"40499fb4-e60c-43d7-8b98-0de3ca44e0eb\" = true\n\n# reverse two actions\n\"9730cdd5-ef27-494b-afd3-5c91ad6c3d9d\" = true\n\n# reversing one action gives the same action\n\"0b828205-51ca-45cd-90d5-f2506013f25f\" = true\n\n# reversing no actions still gives no actions\n\"9949e2ac-6c9c-4330-b685-2089ab28b05f\" = true\n\n# all possible actions\n\"23fdca98-676b-4848-970d-cfed7be39f81\" = true\n\n# reverse all possible actions\n\"ae8fe006-d910-4d6f-be00-54b7c3799e79\" = true\n\n# do nothing for zero\n\"3d36da37-b31f-4cdb-a396-d93a2ee1c4a5\" = true\n"
  },
  {
    "path": "exercises/practice/secret-handshake/.meta/version",
    "content": "1.2.0\n"
  },
  {
    "path": "exercises/practice/secret-handshake/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/secret-handshake/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/secret-handshake/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/secret-handshake/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/secret-handshake/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/secret-handshake/src/main/kotlin/HandshakeCalculator.kt",
    "content": "object HandshakeCalculator {\n    fun calculateHandshake(number: Int): List<Signal> {\n        TODO(\"Implement the function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/secret-handshake/src/main/kotlin/Signal.kt",
    "content": "enum class Signal {\n\n  WINK, DOUBLE_BLINK, CLOSE_YOUR_EYES, JUMP\n\n}\n"
  },
  {
    "path": "exercises/practice/secret-handshake/src/test/kotlin/HandshakeCalculatorTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass HandshakeCalculatorTest {\n\n    @Test\n    fun testThatInput1YieldsAWink() {\n        assertEquals(\n            listOf(Signal.WINK),\n            HandshakeCalculator.calculateHandshake(1))\n    }\n\n    @Ignore\n    @Test\n    fun testThatInput2YieldsADoubleBlink() {\n        assertEquals(\n            listOf(Signal.DOUBLE_BLINK),\n            HandshakeCalculator.calculateHandshake(2))\n    }\n\n    @Ignore\n    @Test\n    fun testThatInput4YieldsACloseYourEyes() {\n        assertEquals(\n            listOf(Signal.CLOSE_YOUR_EYES),\n            HandshakeCalculator.calculateHandshake(4))\n    }\n\n    @Ignore\n    @Test\n    fun testThatInput8YieldsAJump() {\n        assertEquals(\n            listOf(Signal.JUMP),\n            HandshakeCalculator.calculateHandshake(8))\n    }\n\n    @Ignore\n    @Test\n    fun testAnInputThatYieldsTwoActions() {\n        assertEquals(\n            listOf(Signal.WINK, Signal.DOUBLE_BLINK),\n            HandshakeCalculator.calculateHandshake(3))\n    }\n\n    @Ignore\n    @Test\n    fun testAnInputThatYieldsTwoReversedActions() {\n        assertEquals(\n            listOf(Signal.DOUBLE_BLINK, Signal.WINK),\n            HandshakeCalculator.calculateHandshake(19))\n    }\n\n    @Ignore\n    @Test\n    fun testReversingASingleActionYieldsTheSameAction() {\n        assertEquals(\n            listOf(Signal.JUMP),\n            HandshakeCalculator.calculateHandshake(24))\n    }\n\n    @Ignore\n    @Test\n    fun testReversingNoActionsYieldsNoActions() {\n        assertEquals(\n            emptyList(),\n            HandshakeCalculator.calculateHandshake(16))\n    }\n\n    @Ignore\n    @Test\n    fun testInputThatYieldsAllActions() {\n        assertEquals(\n            listOf(Signal.WINK, Signal.DOUBLE_BLINK, Signal.CLOSE_YOUR_EYES, Signal.JUMP),\n            HandshakeCalculator.calculateHandshake(15))\n    }\n\n    @Ignore\n    @Test\n    fun testInputThatYieldsAllActionsReversed() {\n        assertEquals(\n            listOf(Signal.JUMP, Signal.CLOSE_YOUR_EYES, Signal.DOUBLE_BLINK, Signal.WINK),\n            HandshakeCalculator.calculateHandshake(31))\n    }\n\n    @Ignore\n    @Test\n    fun testThatInput0YieldsNoActions() {\n        assertEquals(\n            emptyList(),\n            HandshakeCalculator.calculateHandshake(0))\n    }\n\n    @Ignore\n    @Test\n    fun testThatInputWithLower5BitsNotSetYieldsNoActions() {\n        assertEquals(\n            emptyList(),\n            HandshakeCalculator.calculateHandshake(32))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/series/.docs/instructions.md",
    "content": "# Instructions\n\nGiven a string of digits, output all the contiguous substrings of length `n` in that string in the order that they appear.\n\nFor example, the string \"49142\" has the following 3-digit series:\n\n- \"491\"\n- \"914\"\n- \"142\"\n\nAnd the following 4-digit series:\n\n- \"4914\"\n- \"9142\"\n\nAnd if you ask for a 6-digit series from a 5-digit string, you deserve whatever you get.\n\nNote that these series are only required to occupy _adjacent positions_ in the input;\nthe digits need not be _numerically consecutive_.\n"
  },
  {
    "path": "exercises/practice/series/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"mikegehard\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Series.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/SeriesTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Series.kt\"\n    ]\n  },\n  \"blurb\": \"Given a string of digits, output all the contiguous substrings of length `n` in that string.\",\n  \"source\": \"A subset of the Problem 8 at Project Euler\",\n  \"source_url\": \"https://projecteuler.net/problem=8\"\n}\n"
  },
  {
    "path": "exercises/practice/series/.meta/src/reference/kotlin/Series.kt",
    "content": "object Series {\n    fun Char.toDigitValue() = this.code - '0'.code\n\n    fun slices(n: Int, s: String): List<List<Int>> =\n        when {\n            (n > s.length) -> throw IllegalArgumentException(\"slice length cannot be greater than series length\")\n            (n == 0) -> throw IllegalArgumentException(\"slice length cannot be zero\")\n            (n < 0) -> throw IllegalArgumentException(\"slice length cannot be negative\")\n            (s == \"\") -> throw IllegalArgumentException(\"series cannot be empty\")\n            else -> s.dropLast(n - 1)\n                .mapIndexed { index, _ ->\n                    s.subSequence(index, index + n).map { it.toDigitValue() }\n                }\n        }\n}\n"
  },
  {
    "path": "exercises/practice/series/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# slices of one from one\n\"7ae7a46a-d992-4c2a-9c15-a112d125ebad\" = true\n\n# slices of one from two\n\"3143b71d-f6a5-4221-aeae-619f906244d2\" = true\n\n# slices of two\n\"dbb68ff5-76c5-4ccd-895a-93dbec6d5805\" = true\n\n# slices of two overlap\n\"19bbea47-c987-4e11-a7d1-e103442adf86\" = true\n\n# slices can include duplicates\n\"8e17148d-ba0a-4007-a07f-d7f87015d84c\" = true\n\n# slices of a long series\n\"bd5b085e-f612-4f81-97a8-6314258278b0\" = true\n\n# slice length is too large\n\"6d235d85-46cf-4fae-9955-14b6efef27cd\" = true\n\n# slice length cannot be zero\n\"d34004ad-8765-4c09-8ba1-ada8ce776806\" = true\n\n# slice length cannot be negative\n\"10ab822d-8410-470a-a85d-23fbeb549e54\" = true\n\n# empty series is invalid\n\"c7ed0812-0e4b-4bf3-99c4-28cbbfc246a2\" = true\n"
  },
  {
    "path": "exercises/practice/series/.meta/version",
    "content": "1.0.0\n"
  },
  {
    "path": "exercises/practice/series/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/series/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/series/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/series/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/series/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/series/src/main/kotlin/Series.kt",
    "content": "object Series {\n\n    fun slices(n: Int, s: String): List<List<Int>> {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/series/src/test/kotlin/SeriesTest.kt",
    "content": "import kotlin.test.Test\nimport kotlin.test.Ignore\nimport kotlin.test.assertEquals\n\nclass SeriesTest {\n\n    @Test\n    fun slicesOfOneFromOne() {\n        assertEquals(\n                listOf(listOf(1)),\n                Series.slices(1, \"1\")\n        )\n    }\n\n    @Ignore\n    @Test\n    fun slicesOfOneFromTwo() {\n        assertEquals(\n                listOf(listOf(1), listOf(2)),\n                Series.slices(1, \"12\")\n        )\n    }\n\n    @Ignore\n    @Test\n    fun slicesOfTwo() {\n        assertEquals(\n                listOf(listOf(3,5)),\n                Series.slices(2, \"35\")\n        )\n    }\n\n    @Ignore\n    @Test\n    fun slicesOfTwoOverlap() {\n        assertEquals(\n                listOf(listOf(9,1), listOf(1,4), listOf(4,2)),\n                Series.slices(2, \"9142\")\n        )\n    }\n\n    @Ignore\n    @Test\n    fun slicesCanIncludeDuplicates() {\n        assertEquals(\n                listOf(listOf(7,7,7), listOf(7,7,7), listOf(7,7,7), listOf(7,7,7)),\n                Series.slices(3, \"777777\")\n        )\n    }\n\n    @Ignore\n    @Test\n    fun slicesOfALongSeries() {\n        assertEquals(\n                listOf(listOf(9,1,8,4,9),\n                        listOf(1,8,4,9,3),\n                        listOf(8,4,9,3,9),\n                        listOf(4,9,3,9,0),\n                        listOf(9,3,9,0,4),\n                        listOf(3,9,0,4,2),\n                        listOf(9,0,4,2,4),\n                        listOf(0,4,2,4,3)),\n                Series.slices(5, \"918493904243\")\n        )\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun sliceLengthIsTooLarge() {\n        Series.slices(4, \"123\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun sliceLengthCannotBeZero() {\n        Series.slices(0, \"123\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun sliceLengthCannotBeNegative() {\n        Series.slices(-2, \"123\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun emptySeriesIsInvalid() {\n        Series.slices(1, \"\")\n        Series.slices(1, \"\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/sieve/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to create a program that implements the Sieve of Eratosthenes algorithm to find all prime numbers less than or equal to a given number.\n\nA prime number is a number larger than 1 that is only divisible by 1 and itself.\nFor example, 2, 3, 5, 7, 11, and 13 are prime numbers.\nBy contrast, 6 is _not_ a prime number as it not only divisible by 1 and itself, but also by 2 and 3.\n\nTo use the Sieve of Eratosthenes, first, write out all the numbers from 2 up to and including your given number.\nThen, follow these steps:\n\n1. Find the next unmarked number (skipping over marked numbers).\n   This is a prime number.\n2. Mark all the multiples of that prime number as **not** prime.\n\nRepeat the steps until you've gone through every number.\nAt the end, all the unmarked numbers are prime.\n\n~~~~exercism/note\nThe Sieve of Eratosthenes marks off multiples of each prime using addition (repeatedly adding the prime) or multiplication (directly computing its multiples), rather than checking each number for divisibility.\n\nThe tests don't check that you've implemented the algorithm, only that you've come up with the correct primes.\n~~~~\n\n## Example\n\nLet's say you're finding the primes less than or equal to 10.\n\n- Write out 2, 3, 4, 5, 6, 7, 8, 9, 10, leaving them all unmarked.\n\n  ```text\n  2 3 4 5 6 7 8 9 10\n  ```\n\n- 2 is unmarked and is therefore a prime.\n  Mark 4, 6, 8 and 10 as \"not prime\".\n\n  ```text\n  2 3 [4] 5 [6] 7 [8] 9 [10]\n  ↑\n  ```\n\n- 3 is unmarked and is therefore a prime.\n  Mark 6 and 9 as not prime _(marking 6 is optional - as it's already been marked)_.\n\n  ```text\n  2 3 [4] 5 [6] 7 [8] [9] [10]\n    ↑\n  ```\n\n- 4 is marked as \"not prime\", so we skip over it.\n\n  ```text\n  2 3 [4] 5 [6] 7 [8] [9] [10]\n       ↑\n  ```\n\n- 5 is unmarked and is therefore a prime.\n  Mark 10 as not prime _(optional - as it's already been marked)_.\n\n  ```text\n  2 3 [4] 5 [6] 7 [8] [9] [10]\n          ↑\n  ```\n\n- 6 is marked as \"not prime\", so we skip over it.\n\n  ```text\n  2 3 [4] 5 [6] 7 [8] [9] [10]\n             ↑\n  ```\n\n- 7 is unmarked and is therefore a prime.\n\n  ```text\n  2 3 [4] 5 [6] 7 [8] [9] [10]\n                ↑\n  ```\n\n- 8 is marked as \"not prime\", so we skip over it.\n\n  ```text\n  2 3 [4] 5 [6] 7 [8] [9] [10]\n                   ↑\n  ```\n\n- 9 is marked as \"not prime\", so we skip over it.\n\n  ```text\n  2 3 [4] 5 [6] 7 [8] [9] [10]\n                       ↑\n  ```\n\n- 10 is marked as \"not prime\", so we stop as there are no more numbers to check.\n\n  ```text\n  2 3 [4] 5 [6] 7 [8] [9] [10]\n                           ↑\n  ```\n\nYou've examined all the numbers and found that 2, 3, 5, and 7 are still unmarked, meaning they're the primes less than or equal to 10.\n"
  },
  {
    "path": "exercises/practice/sieve/.docs/introduction.md",
    "content": "# Introduction\n\nYou bought a big box of random computer parts at a garage sale.\nYou've started putting the parts together to build custom computers.\n\nYou want to test the performance of different combinations of parts, and decide to create your own benchmarking program to see how your computers compare.\nYou choose the famous \"Sieve of Eratosthenes\" algorithm, an ancient algorithm, but one that should push your computers to the limits.\n"
  },
  {
    "path": "exercises/practice/sieve/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Sieve.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/SieveTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Sieve.kt\"\n    ]\n  },\n  \"blurb\": \"Use the Sieve of Eratosthenes to find all the primes from 2 up to a given number.\",\n  \"source\": \"Sieve of Eratosthenes at Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes\"\n}\n"
  },
  {
    "path": "exercises/practice/sieve/.meta/src/reference/kotlin/Sieve.kt",
    "content": "object Sieve {\n    fun primesUpTo(upperBound: Int): List<Int> {\n        val primes = mutableListOf<Int>()\n        var candidates = (2..upperBound).toList()\n        while (candidates.isNotEmpty()) {\n            val prime = candidates[0]\n            primes += prime\n            candidates = candidates.filterIndexed { index, value -> index != 0 && value % prime != 0 }\n        }\n\n        return primes\n    }\n}\n"
  },
  {
    "path": "exercises/practice/sieve/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# no primes under two\n\"88529125-c4ce-43cc-bb36-1eb4ddd7b44f\" = true\n\n# find first prime\n\"4afe9474-c705-4477-9923-840e1024cc2b\" = true\n\n# find primes up to 10\n\"974945d8-8cd9-4f00-9463-7d813c7f17b7\" = true\n\n# limit is prime\n\"2e2417b7-3f3a-452a-8594-b9af08af6d82\" = true\n\n# find primes up to 1000\n\"92102a05-4c7c-47de-9ed0-b7d5fcd00f21\" = true\n"
  },
  {
    "path": "exercises/practice/sieve/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/sieve/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/sieve/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/sieve/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/sieve/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/sieve/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/sieve/src/main/kotlin/Sieve.kt",
    "content": "object Sieve {\n\n    fun primesUpTo(upperBound: Int): List<Int> {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/sieve/src/test/kotlin/SieveTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass SieveTest {\n\n    @Test\n    fun noPrimesUnder2() {\n        val expectedOutput = emptyList<Int>()\n\n        assertEquals(expectedOutput, Sieve.primesUpTo(1))\n    }\n\n    @Ignore\n    @Test\n    fun findFirstPrime() {\n        val expectedOutput = listOf(2)\n\n        assertEquals(expectedOutput, Sieve.primesUpTo(2))\n    }\n\n    @Ignore\n    @Test\n    fun findPrimesUpTo10() {\n        val expectedOutput = listOf(2, 3, 5, 7)\n\n        assertEquals(expectedOutput, Sieve.primesUpTo(10))\n    }\n\n    @Ignore\n    @Test\n    fun findPrimesUpTo1000() {\n        val expectedOutput = listOf(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,\n                67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173,\n                179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283,\n                293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421,\n                431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563,\n                569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683,\n                691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829,\n                839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983,\n                991, 997)\n\n        assertEquals(expectedOutput, Sieve.primesUpTo(1000))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/simple-cipher/.docs/instructions.md",
    "content": "# Instructions\n\nImplement a simple shift cipher like Caesar and a more secure substitution cipher.\n\n## Step 1\n\n\"If he had anything confidential to say, he wrote it in cipher, that is, by so changing the order of the letters of the alphabet, that not a word could be made out.\nIf anyone wishes to decipher these, and get at their meaning, he must substitute the fourth letter of the alphabet, namely D, for A, and so with the others.\"\n—Suetonius, Life of Julius Caesar\n\nCiphers are very straight-forward algorithms that allow us to render text less readable while still allowing easy deciphering.\nThey are vulnerable to many forms of cryptanalysis, but Caesar was lucky that his enemies were not cryptanalysts.\n\nThe Caesar cipher was used for some messages from Julius Caesar that were sent afield.\nNow Caesar knew that the cipher wasn't very good, but he had one ally in that respect: almost nobody could read well.\nSo even being a couple letters off was sufficient so that people couldn't recognize the few words that they did know.\n\nYour task is to create a simple shift cipher like the Caesar cipher.\nThis image is a great example of the Caesar cipher:\n\n![Caesar cipher][img-caesar-cipher]\n\nFor example:\n\nGiving \"iamapandabear\" as input to the encode function returns the cipher \"ldpdsdqgdehdu\".\nObscure enough to keep our message secret in transit.\n\nWhen \"ldpdsdqgdehdu\" is put into the decode function it would return the original \"iamapandabear\" letting your friend read your original message.\n\n## Step 2\n\nShift ciphers quickly cease to be useful when the opposition commander figures them out.\nSo instead, let's try using a substitution cipher.\nTry amending the code to allow us to specify a key and use that for the shift distance.\n\nHere's an example:\n\nGiven the key \"aaaaaaaaaaaaaaaaaa\", encoding the string \"iamapandabear\"\nwould return the original \"iamapandabear\".\n\nGiven the key \"ddddddddddddddddd\", encoding our string \"iamapandabear\"\nwould return the obscured \"ldpdsdqgdehdu\"\n\nIn the example above, we've set a = 0 for the key value.\nSo when the plaintext is added to the key, we end up with the same message coming out.\nSo \"aaaa\" is not an ideal key.\nBut if we set the key to \"dddd\", we would get the same thing as the Caesar cipher.\n\n## Step 3\n\nThe weakest link in any cipher is the human being.\nLet's make your substitution cipher a little more fault tolerant by providing a source of randomness and ensuring that the key contains only lowercase letters.\n\nIf someone doesn't submit a key at all, generate a truly random key of at least 100 lowercase characters in length.\n\n## Extensions\n\nShift ciphers work by making the text slightly odd, but are vulnerable to frequency analysis.\nSubstitution ciphers help that, but are still very vulnerable when the key is short or if spaces are preserved.\nLater on you'll see one solution to this problem in the exercise \"crypto-square\".\n\nIf you want to go farther in this field, the questions begin to be about how we can exchange keys in a secure way.\nTake a look at [Diffie-Hellman on Wikipedia][dh] for one of the first implementations of this scheme.\n\n[img-caesar-cipher]: https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Caesar_cipher_left_shift_of_3.svg/320px-Caesar_cipher_left_shift_of_3.svg.png\n[dh]: https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange\n"
  },
  {
    "path": "exercises/practice/simple-cipher/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"mikegehard\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/SimpleCipher.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/SimpleCipherTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/SimpleCipher.kt\"\n    ]\n  },\n  \"blurb\": \"Implement a simple shift cipher like Caesar and a more secure substitution cipher.\",\n  \"source\": \"Substitution Cipher at Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Substitution_cipher\"\n}\n"
  },
  {
    "path": "exercises/practice/simple-cipher/.meta/src/reference/kotlin/SimpleCipher.kt",
    "content": "import java.util.Random\n\ndata class Cipher(val key: String) {\n\n    constructor() : this(generateRandomKey())\n\n    init {\n        require(key.matches(Regex(\"^[a-z]+$\"))) { \"Invalid key: $key\" }\n    }\n\n    companion object {\n        val random = Random()\n        val alphabet = ('a'..'z').toList()\n\n        private fun generateRandomKey() = generateSequence { alphabet[random.nextInt(alphabet.size)] }.take(100).joinToString(\"\")\n    }\n\n    fun encode(s: String): String = s.mapIndexed { index, char ->  encodeChar(char, index)}.joinToString(\"\")\n    fun decode(s: String): String = s.mapIndexed { index, char ->  decodeChar(char, index)}.joinToString(\"\")\n\n    private fun encodeChar(character: Char, index: Int): Char {\n        var alphaIdx = alphabet.indexOf(character) + alphabet.indexOf(key[index % key.length])\n        if(alphaIdx >= alphabet.size) alphaIdx -= alphabet.size\n\n        return alphabet[alphaIdx]\n    }\n\n    private fun decodeChar(character: Char, index: Int): Char {\n        var alphaIdx = alphabet.indexOf(character) - alphabet.indexOf(key[index % key.length])\n        if(alphaIdx < 0) alphaIdx += alphabet.size\n\n        return alphabet[alphaIdx]\n    }\n}\n"
  },
  {
    "path": "exercises/practice/simple-cipher/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# Can encode\n\"b8bdfbe1-bea3-41bb-a999-b41403f2b15d\" = true\n\n# Can decode\n\"3dff7f36-75db-46b4-ab70-644b3f38b81c\" = true\n\n# Is reversible. I.e., if you apply decode in a encoded result, you must see the same plaintext encode parameter as a result of the decode method\n\"8143c684-6df6-46ba-bd1f-dea8fcb5d265\" = true\n\n# Key is made only of lowercase letters\n\"defc0050-e87d-4840-85e4-51a1ab9dd6aa\" = true\n\n# Can encode\n\"565e5158-5b3b-41dd-b99d-33b9f413c39f\" = true\n\n# Can decode\n\"d44e4f6a-b8af-4e90-9d08-fd407e31e67b\" = true\n\n# Is reversible. I.e., if you apply decode in a encoded result, you must see the same plaintext encode parameter as a result of the decode method\n\"70a16473-7339-43df-902d-93408c69e9d1\" = true\n\n# Can double shift encode\n\"69a1458b-92a6-433a-a02d-7beac3ea91f9\" = true\n\n# Can wrap on encode\n\"21d207c1-98de-40aa-994f-86197ae230fb\" = true\n\n# Can wrap on decode\n\"a3d7a4d7-24a9-4de6-bdc4-a6614ced0cb3\" = true\n\n# Can encode messages longer than the key\n\"e31c9b8c-8eb6-45c9-a4b5-8344a36b9641\" = true\n\n# Can decode messages longer than the key\n\"93cfaae0-17da-4627-9a04-d6d1e1be52e3\" = true\n"
  },
  {
    "path": "exercises/practice/simple-cipher/.meta/version",
    "content": "2.0.0\n"
  },
  {
    "path": "exercises/practice/simple-cipher/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/simple-cipher/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/simple-cipher/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/simple-cipher/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/simple-cipher/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/simple-cipher/src/main/kotlin/SimpleCipher.kt",
    "content": "data class Cipher(val todo: Nothing) {\n\n    // TODO: Implement proper constructor\n\n    fun encode(s: String): String {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun decode(s: String): String {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/simple-cipher/src/test/kotlin/IncorrectKeyCipherTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\n\n/**\n * Extra tests\n */\nclass IncorrectKeyCipherTest {\n\n    @Test(expected = IllegalArgumentException::class)\n    fun  `key cannot consist of upper cased letters`() {\n        Cipher(\"ABCDEF\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `key cannot contain upper cased letters`() {\n        Cipher(\"abcdEFg\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `key cannot consist of digits`() {\n        Cipher(\"12345\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `key cannot contain digits`() {\n        Cipher(\"abcd345ef\")\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `key cannot be empty`() {\n        Cipher(\"\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/simple-cipher/src/test/kotlin/RandomKeyCipherTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\nimport kotlin.test.assertNotEquals\nimport kotlin.test.assertTrue\n\nclass RandomKeyCipherTest {\n\n    @Test\n    fun `can encode`() = with(Cipher()) {\n        assertEquals(key.substring(0, 10), encode(\"aaaaaaaaaa\"))\n    }\n\n    @Ignore\n    @Test\n    fun `can decode`() = with(Cipher()) {\n        assertEquals(\"aaaaaaaaaa\", decode(key.substring(0, 10)))\n    }\n\n    @Ignore\n    @Test\n    fun `key is made only of lowercase letters`() {\n        assertTrue(Cipher().key.matches(Regex(\"[a-z]+\")))\n    }\n\n    @Ignore\n    @Test\n    fun `is reversible`() {\n        val plainText = \"abcdefghij\"\n        with(Cipher()) { assertEquals(plainText, decode(encode(plainText))) }\n    }\n\n    // extra tests\n\n    @Ignore\n    @Test\n    fun `default key is of length 100`() {\n        assertEquals(100, Cipher().key.length)\n    }\n\n    @Ignore\n    @Test\n    fun `two default generated keys differs`() {\n        assertNotEquals(Cipher().key, Cipher().key)\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/simple-cipher/src/test/kotlin/SimpleCipherTest.kt",
    "content": "import org.junit.runner.RunWith\nimport org.junit.runners.Suite\n\n@RunWith(Suite::class)\n@Suite.SuiteClasses(\n        RandomKeyCipherTest::class,\n        IncorrectKeyCipherTest::class,\n        SubstitutionCipherTest::class\n)\nclass SimpleCipherTest {\n}\n"
  },
  {
    "path": "exercises/practice/simple-cipher/src/test/kotlin/SubstitutionCipherTest.kt",
    "content": "import org.junit.Before\nimport org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass SubstitutionCipherTest {\n\n    @Test\n    fun `can encode`() = \"abcdefghij\".let { assertEquals(it, Cipher(it).encode(\"aaaaaaaaaa\")) }\n\n    @Ignore\n    @Test\n    fun `can decode`() = \"abcdefghij\".let { assertEquals(\"aaaaaaaaaa\", Cipher(it).decode(it)) }\n\n    @Ignore\n    @Test\n    fun `is reversible`() = with(Cipher(\"abcdefghij\")) { assertEquals(key, decode(encode(key))) }\n\n    @Ignore\n    @Test\n    fun `can double shift encode`() =\n        \"iamapandabear\".let { assertEquals(\"qayaeaagaciai\", Cipher(it).encode(it)) }\n\n    @Ignore\n    @Test\n    fun `can wrap on encode`() =\n        assertEquals(\"zabcdefghi\", Cipher(\"abcdefghij\").encode(\"zzzzzzzzzz\"))\n\n    @Ignore\n    @Test\n    fun `can wrap on decode`() =\n        assertEquals(\"zzzzzzzzzz\", Cipher(\"abcdefghij\").decode(\"zabcdefghi\"))\n\n    @Ignore\n    @Test\n    fun `can encode messages longer than the key`() =\n        assertEquals(\"iboaqcnecbfcr\", Cipher(\"abc\").encode(\"iamapandabear\"))\n\n    @Ignore\n    @Test\n    fun `can decode messages longer than the key`() =\n        assertEquals(\"iamapandabear\", Cipher(\"abc\").decode(\"iboaqcnecbfcr\"))\n\n    // extra tests\n\n    @Ignore\n    @Test\n    fun `keeps the given key`() = \"abcdefghij\".let { assertEquals(it, Cipher(it).key) }\n\n\n}\n"
  },
  {
    "path": "exercises/practice/space-age/.docs/instructions.md",
    "content": "# Instructions\n\nGiven an age in seconds, calculate how old someone would be on a planet in our Solar System.\n\nOne Earth year equals 365.25 Earth days, or 31,557,600 seconds.\nIf you were told someone was 1,000,000,000 seconds old, their age would be 31.69 Earth-years.\n\nFor the other planets, you have to account for their orbital period in Earth Years:\n\n| Planet  | Orbital period in Earth Years |\n| ------- | ----------------------------- |\n| Mercury | 0.2408467                     |\n| Venus   | 0.61519726                    |\n| Earth   | 1.0                           |\n| Mars    | 1.8808158                     |\n| Jupiter | 11.862615                     |\n| Saturn  | 29.447498                     |\n| Uranus  | 84.016846                     |\n| Neptune | 164.79132                     |\n\n~~~~exercism/note\nThe actual length of one complete orbit of the Earth around the sun is closer to 365.256 days (1 sidereal year).\nThe Gregorian calendar has, on average, 365.2425 days.\nWhile not entirely accurate, 365.25 is the value used in this exercise.\nSee [Year on Wikipedia][year] for more ways to measure a year.\n\n[year]: https://en.wikipedia.org/wiki/Year#Summary\n~~~~\n"
  },
  {
    "path": "exercises/practice/space-age/.docs/introduction.md",
    "content": "# Introduction\n\nThe 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).\nThe first stop is Mercury, where customs require you to fill out a form (bureaucracy is apparently _not_ Earth-specific).\nAs you hand over the form to the customs officer, they scrutinize it and frown.\n\"Do you _really_ expect me to believe you're just 50 years old?\nYou must be closer to 200 years old!\"\n\nAmused, you wait for the customs officer to start laughing, but they appear to be dead serious.\nYou realize that you've entered your age in _Earth years_, but the officer expected it in _Mercury years_!\nAs Mercury's orbital period around the sun is significantly shorter than Earth, you're actually a lot older in Mercury years.\nAfter some quick calculations, you're able to provide your age in Mercury Years.\nThe customs officer smiles, satisfied, and waves you through.\nYou make a mental note to pre-calculate your planet-specific age _before_ future customs checks, to avoid such mix-ups.\n\n~~~~exercism/note\nIf you're wondering why Pluto didn't make the cut, go watch [this YouTube video][pluto-video].\n\n[pluto-video]: https://www.youtube.com/watch?v=Z_2gbGXzFbs\n~~~~\n"
  },
  {
    "path": "exercises/practice/space-age/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sanderploegsma\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/SpaceAge.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/SpaceAgeTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/SpaceAge.kt\"\n    ]\n  },\n  \"blurb\": \"Given an age in seconds, calculate how old someone is in terms of a given planet's solar years.\",\n  \"source\": \"Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial.\",\n  \"source_url\": \"https://pine.fm/LearnToProgram/?Chapter=01\"\n}\n"
  },
  {
    "path": "exercises/practice/space-age/.meta/src/reference/kotlin/SpaceAge.kt",
    "content": "class SpaceAge(private val seconds: Long) {\n\n    companion object {\n        const val EARTH_ORBITAL_PERIOD_IN_SECONDS = 31557600.0\n\n        private enum class Planet(val relativeOrbitalPeriod: Double) {\n            EARTH(1.0),\n            MERCURY(0.2408467),\n            VENUS(0.61519726),\n            MARS(1.8808158),\n            JUPITER(11.862615),\n            SATURN(29.447498),\n            URANUS(84.016846),\n            NEPTUNE(164.79132)\n        }\n    }\n\n    fun onEarth() = calculateAge(Planet.EARTH)\n    fun onMercury() = calculateAge(Planet.MERCURY)\n    fun onVenus() = calculateAge(Planet.VENUS)\n    fun onMars() = calculateAge(Planet.MARS)\n    fun onJupiter() = calculateAge(Planet.JUPITER)\n    fun onSaturn() = calculateAge(Planet.SATURN)\n    fun onUranus() = calculateAge(Planet.URANUS)\n    fun onNeptune() = calculateAge(Planet.NEPTUNE)\n\n    private fun calculateAge(planet: Planet): Double = \n        seconds / (EARTH_ORBITAL_PERIOD_IN_SECONDS * planet.relativeOrbitalPeriod)\n}\n"
  },
  {
    "path": "exercises/practice/space-age/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# age on Earth\n\"84f609af-5a91-4d68-90a3-9e32d8a5cd34\" = true\n\n# age on Mercury\n\"ca20c4e9-6054-458c-9312-79679ffab40b\" = true\n\n# age on Venus\n\"502c6529-fd1b-41d3-8fab-65e03082b024\" = true\n\n# age on Mars\n\"9ceadf5e-a0d5-4388-9d40-2c459227ceb8\" = true\n\n# age on Jupiter\n\"42927dc3-fe5e-4f76-a5b5-f737fc19bcde\" = true\n\n# age on Saturn\n\"8469b332-7837-4ada-b27c-00ee043ebcad\" = true\n\n# age on Uranus\n\"999354c1-76f8-4bb5-a672-f317b6436743\" = true\n\n# age on Neptune\n\"80096d30-a0d4-4449-903e-a381178355d8\" = true\n"
  },
  {
    "path": "exercises/practice/space-age/.meta/version",
    "content": "1.2.0\n"
  },
  {
    "path": "exercises/practice/space-age/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/space-age/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/space-age/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/space-age/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/space-age/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/space-age/src/main/kotlin/SpaceAge.kt",
    "content": "class SpaceAge {\n\n    // TODO: Implement proper constructor\n\n    fun onEarth(): Double = TODO(\"Implement this function to complete the task\")\n    fun onMercury(): Double = TODO(\"Implement this function to complete the task\")\n    fun onVenus(): Double = TODO(\"Implement this function to complete the task\")\n    fun onMars(): Double = TODO(\"Implement this function to complete the task\")\n    fun onJupiter(): Double = TODO(\"Implement this function to complete the task\")\n    fun onSaturn(): Double = TODO(\"Implement this function to complete the task\")\n    fun onUranus(): Double = TODO(\"Implement this function to complete the task\")\n    fun onNeptune(): Double = TODO(\"Implement this function to complete the task\")\n}\n"
  },
  {
    "path": "exercises/practice/space-age/src/test/kotlin/SpaceAgeTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass SpaceAgeTest {\n    @Test\n    fun `age on Earth`() = assertYearsEqual(31.69, SpaceAge(1000000000).onEarth())\n\n    @Ignore\n    @Test\n    fun `age on Mercury`() = assertYearsEqual(280.88, SpaceAge(2134835688).onMercury())\n\n    @Ignore\n    @Test\n    fun `age on Venus`() = assertYearsEqual(9.78, SpaceAge(189839836).onVenus())\n\n    @Ignore\n    @Test\n    fun `age on Mars`() = assertYearsEqual(35.88, SpaceAge(2129871239).onMars())\n\n    @Ignore\n    @Test\n    fun `age on Jupiter`() = assertYearsEqual(2.41, SpaceAge(901876382).onJupiter())\n\n    @Ignore\n    @Test\n    fun `age on Saturn`() = assertYearsEqual(2.15, SpaceAge(2000000000).onSaturn())\n\n    @Ignore\n    @Test\n    fun `age on Uranus`() = assertYearsEqual(0.46, SpaceAge(1210123456).onUranus())\n\n    @Ignore\n    @Test\n    fun `age on Neptune`() = assertYearsEqual(0.35, SpaceAge(1821023456).onNeptune())\n}\n\nprivate const val TOLERANCE = 0.01\n\nprivate fun assertYearsEqual(expectedYears: Double, actualYears: Double) = \n    assertEquals(expectedYears, actualYears, absoluteTolerance = TOLERANCE)\n"
  },
  {
    "path": "exercises/practice/spiral-matrix/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to return a square matrix of a given size.\n\nThe 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:\n\n## Examples\n\n### Spiral matrix of size 3\n\n```text\n1 2 3\n8 9 4\n7 6 5\n```\n\n### Spiral matrix of size 4\n\n```text\n 1  2  3 4\n12 13 14 5\n11 16 15 6\n10  9  8 7\n```\n"
  },
  {
    "path": "exercises/practice/spiral-matrix/.docs/introduction.md",
    "content": "# Introduction\n\nIn a small village near an ancient forest, there was a legend of a hidden treasure buried deep within the woods.\nDespite numerous attempts, no one had ever succeeded in finding it.\nThis was about to change, however, thanks to a young explorer named Elara.\nShe had discovered an old document containing instructions on how to locate the treasure.\nUsing these instructions, Elara was able to draw a map that revealed the path to the treasure.\n\nTo her surprise, the path followed a peculiar clockwise spiral.\nIt was no wonder no one had been able to find the treasure before!\nWith the map in hand, Elara embarks on her journey to uncover the hidden treasure.\n"
  },
  {
    "path": "exercises/practice/spiral-matrix/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/SpiralMatrix.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/SpiralMatrixTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/SpiralMatrix.kt\"\n    ]\n  },\n  \"blurb\": \"Given the size, return a square matrix of numbers in spiral order.\",\n  \"source\": \"Reddit r/dailyprogrammer challenge #320 [Easy] Spiral Ascension.\",\n  \"source_url\": \"https://web.archive.org/web/20230607064729/https://old.reddit.com/r/dailyprogrammer/comments/6i60lr/20170619_challenge_320_easy_spiral_ascension/\"\n}\n"
  },
  {
    "path": "exercises/practice/spiral-matrix/.meta/src/reference/kotlin/SpiralMatrix.kt",
    "content": "import Direction.RIGHT\nimport kotlin.math.pow\n\nenum class Direction(val dx: Int, val dy: Int) {\n    UP   ( 0, -1),\n    RIGHT( 1,  0),\n    DOWN ( 0,  1),\n    LEFT (-1,  0);\n\n    fun turnRight() = Direction.values()[(ordinal + 1) % Direction.values().size]\n}\n\ndata class Coordinate(val x: Int, val y: Int) {\n\n    fun step(direction: Direction) = copy(x + direction.dx, y + direction.dy)\n\n    fun isWithinGridOfSize(size: Int) = x in 0 until size && y in 0 until size\n\n}\n\nobject SpiralMatrix {\n\n    fun ofSize(size: Int): Array<IntArray> {\n        require(size >= 0) { \"size must be a non-negative integer\" }\n\n        if (size == 0) return emptyArray()\n\n        val result = Array(size) { IntArray(size) { 0 } }\n        val entryCount = size.toDouble().pow(2.0).toInt()\n\n        var coord = Coordinate(0, 0)\n        var direction = RIGHT\n\n        for (i in 0 until entryCount) {\n            result[coord.y][coord.x] = i + 1\n\n            val maybeNextCoord = coord.step(direction)\n            if (maybeNextCoord.isWithinGridOfSize(size) && result[maybeNextCoord.y][maybeNextCoord.x] == 0) {\n                coord = maybeNextCoord\n            } else {\n                direction = direction.turnRight()\n                coord = coord.step(direction)\n            }\n        }\n\n        return result\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/spiral-matrix/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# empty spiral\n\"8f584201-b446-4bc9-b132-811c8edd9040\" = true\n\n# trivial spiral\n\"e40ae5f3-e2c9-4639-8116-8a119d632ab2\" = true\n\n# spiral of size 2\n\"cf05e42d-eb78-4098-a36e-cdaf0991bc48\" = true\n\n# spiral of size 3\n\"1c475667-c896-4c23-82e2-e033929de939\" = true\n\n# spiral of size 4\n\"05ccbc48-d891-44f5-9137-f4ce462a759d\" = true\n\n# spiral of size 5\n\"f4d2165b-1738-4e0c-bed0-c459045ae50d\" = true\n"
  },
  {
    "path": "exercises/practice/spiral-matrix/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/spiral-matrix/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/spiral-matrix/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/spiral-matrix/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/spiral-matrix/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/spiral-matrix/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/spiral-matrix/src/main/kotlin/SpiralMatrix.kt",
    "content": "object SpiralMatrix {\n\n    fun ofSize(size: Int): Array<IntArray> {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/spiral-matrix/src/test/kotlin/SpiralMatrixTest.kt",
    "content": "import org.junit.Assert.assertArrayEquals\nimport org.junit.Ignore\nimport org.junit.Test\n\nclass SpiralMatrixTest {\n\n    @Test\n    fun testEmptySpiral() {\n        val expected = emptyArray<IntArray>()\n\n        assertArrayEquals(expected, SpiralMatrix.ofSize(0))\n    }\n\n    @Ignore\n    @Test\n    fun testTrivialSpiral() {\n        val expected = arrayOf(\n            intArrayOf(1)\n        )\n\n        assertArrayEquals(expected, SpiralMatrix.ofSize(1))\n    }\n\n    @Ignore\n    @Test\n    fun testSpiralOfSize2() {\n        val expected = arrayOf(\n            intArrayOf(1, 2),\n            intArrayOf(4, 3)\n        )\n\n        assertArrayEquals(expected, SpiralMatrix.ofSize(2))\n    }\n\n    @Ignore\n    @Test\n    fun testSpiralOfSize3() {\n        val expected = arrayOf(\n            intArrayOf(1, 2, 3),\n            intArrayOf(8, 9, 4),\n            intArrayOf(7, 6, 5)\n        )\n\n        assertArrayEquals(expected, SpiralMatrix.ofSize(3))\n    }\n\n    @Ignore\n    @Test\n    fun testSpiralOfSize4() {\n        val expected = arrayOf(\n            intArrayOf( 1,  2,  3,  4),\n            intArrayOf(12, 13, 14,  5),\n            intArrayOf(11, 16, 15,  6),\n            intArrayOf(10,  9,  8,  7)\n        )\n\n        assertArrayEquals(expected, SpiralMatrix.ofSize(4))\n    }\n\n    @Ignore\n    @Test\n    fun testSpiralOfSize5() {\n        val expected = arrayOf(\n            intArrayOf( 1,  2,  3,  4,  5),\n            intArrayOf(16, 17, 18, 19,  6),\n            intArrayOf(15, 24, 25, 20,  7),\n            intArrayOf(14, 23, 22, 21,  8),\n            intArrayOf(13, 12, 11, 10,  9)\n        )\n\n        assertArrayEquals(expected, SpiralMatrix.ofSize(5))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/strain/.docs/instructions.md",
    "content": "# Instructions\n\nImplement the `keep` and `discard` operation on collections. Given a collection\nand a predicate on the collection's elements, `keep` returns a new collection\ncontaining those elements where the predicate is true, while `discard` returns\na new collection containing those elements where the predicate is false.\n\nFor example, given the collection of numbers:\n\n- 1, 2, 3, 4, 5\n\nAnd the predicate:\n\n- is the number even?\n\nThen your keep operation should produce:\n\n- 2, 4\n\nWhile your discard operation should produce:\n\n- 1, 3, 5\n\nNote that the union of keep and discard is all the elements.\n\nThe functions may be called `keep` and `discard`, or they may need different\nnames in order to not clash with existing functions or concepts in your\nlanguage.\n\n## Restrictions\n\nKeep your hands off that filter/reject/whatchamacallit functionality\nprovided by your standard library!  Solve this one yourself using other\nbasic tools instead.\n"
  },
  {
    "path": "exercises/practice/strain/.meta/config.json",
    "content": "{\n  \"blurb\": \"Implement the `keep` and `discard` operation on collections. Given a collection and a predicate on the collection's elements, `keep` returns a new collection containing those elements where the predicate is true, while `discard` returns a new collection containing those elements where the predicate is false.\",\n  \"authors\": [\"sdavids13\"],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\"src/main/kotlin/Strain.kt\"],\n    \"test\": [\"src/test/kotlin/StrainTest.kt\"],\n    \"example\": [\".meta/src/reference/kotlin/Strain.kt\"]\n  },\n  \"source\": \"Conversation with James Edward Gray II\",\n  \"source_url\": \"https://twitter.com/jeg2\"\n}\n"
  },
  {
    "path": "exercises/practice/strain/.meta/src/reference/kotlin/Strain.kt",
    "content": "object Strain {\n    fun <T> keep(collection: List<T>, predicate: (T) -> Boolean): List<T> {\n        val filteredCollection = mutableListOf<T>()\n        collection.forEach { if (predicate(it)) filteredCollection.add(it) }\n\n        return filteredCollection\n    }\n\n    fun <T> discard(collection: List<T>, predicate: (T) -> Boolean) = keep(collection) { value -> !predicate(value) }\n}\n"
  },
  {
    "path": "exercises/practice/strain/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/strain/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/strain/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/strain/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/strain/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/strain/src/main/kotlin/Strain.kt",
    "content": "object Strain {\n\n    fun <T> keep(collection: List<T>, predicate: (T) -> Boolean): List<T> {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun <T> discard(collection: List<T>, predicate: (T) -> Boolean): List<T> {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/strain/src/test/kotlin/StrainTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass StrainTest {\n\n\n    @Test\n    fun emptyKeep() {\n        val input = emptyList<Int>()\n        val expectedOutput = emptyList<Int>()\n        assertEquals(expectedOutput, Strain.keep(input, { it < 10 }))\n    }\n\n    @Ignore\n    @Test\n    fun keepEverything() {\n        val input = listOf(1, 2, 3)\n        val expectedOutput = listOf(1, 2, 3)\n        assertEquals(expectedOutput, Strain.keep(input, { it < 10 }))\n    }\n\n    @Ignore\n    @Test\n    fun keepFirstAndLast() {\n        val input = listOf(1, 2, 3)\n        val expectedOutput = listOf(1, 3)\n        assertEquals(expectedOutput, Strain.keep(input, { it % 2 != 0 }))\n    }\n\n    @Ignore\n    @Test\n    fun keepNeitherFirstNorLast() {\n        val input = listOf(1, 2, 3, 4, 5)\n        val expectedOutput = listOf(2, 4)\n        assertEquals(expectedOutput, Strain.keep(input, { it % 2 == 0 }))\n    }\n\n    @Ignore\n    @Test\n    fun KeepStrings() {\n        val words = \"apple zebra banana zombies cherimoya zelot\".split(\" \")\n        val expectedOutput = listOf(\"zebra\", \"zombies\", \"zelot\")\n        assertEquals(expectedOutput,\n                Strain.keep(words, { it.startsWith(\"z\") }))\n    }\n\n    @Ignore\n    @Test\n    fun keepArrays() {\n        val actual = listOf(\n                listOf(1, 2, 3),\n                listOf(5, 5, 5),\n                listOf(5, 1, 2),\n                listOf(2, 1, 2),\n                listOf(1, 5, 2),\n                listOf(2, 2, 1),\n                listOf(1, 2, 5))\n        val expectedOutput = listOf(\n                listOf(5, 5, 5),\n                listOf(5, 1, 2),\n                listOf(1, 5, 2),\n                listOf(1, 2, 5))\n        assertEquals(expectedOutput,\n                Strain.keep(actual, { col -> col.contains(5) }))\n    }\n\n    @Ignore\n    @Test\n    fun emptyDiscard() {\n        val input = emptyList<Int>()\n        val expectedOutput = emptyList<Int>()\n        assertEquals(expectedOutput, Strain.discard(input, { it < 10 }))\n    }\n\n    @Ignore\n    @Test\n    fun discardNothing() {\n        val input = listOf(1, 2, 3)\n        val expectedOutput = listOf(1, 2, 3)\n        assertEquals(expectedOutput, Strain.discard(input, { it > 10 }))\n    }\n\n    @Ignore\n    @Test\n    fun discardFirstAndLast() {\n        val input = listOf(1, 2, 3)\n        val expectedOutput = listOf(2)\n        assertEquals(expectedOutput, Strain.discard(input, { it % 2 != 0 }))\n\n    }\n\n    @Ignore\n    @Test\n    fun discardNeitherFirstNorLast() {\n        val input = listOf(1, 2, 3, 4, 5)\n        val expectedOutput = listOf(1, 3, 5)\n        assertEquals(expectedOutput, Strain.discard(input, { it % 2 == 0 }))\n    }\n\n    @Ignore\n    @Test\n    fun discardStrings() {\n        val words = \"apple zebra banana zombies cherimoya zelot\".split(\" \")\n        val expectedOutput = listOf(\"apple\", \"banana\", \"cherimoya\")\n        assertEquals(expectedOutput,\n                Strain.discard(words, { it.startsWith(\"z\") }))\n    }\n\n    @Ignore\n    @Test\n    fun discardArrays() {\n        val actual = listOf(\n                listOf(1, 2, 3),\n                listOf(5, 5, 5),\n                listOf(5, 1, 2),\n                listOf(2, 1, 2),\n                listOf(1, 5, 2),\n                listOf(2, 2, 1),\n                listOf(1, 2, 5))\n        val expectedOutput = listOf(\n                listOf(1, 2, 3),\n                listOf(2, 1, 2),\n                listOf(2, 2, 1))\n        assertEquals(expectedOutput,\n                Strain.discard(actual, { col -> col.contains(5) }))\n    }\n}\n"
  },
  {
    "path": "exercises/practice/sublist/.docs/instructions.md",
    "content": "# Instructions\n\nGiven any two lists `A` and `B`, determine if:\n\n- List `A` is equal to list `B`; or\n- List `A` contains list `B` (`A` is a superlist of `B`); or\n- List `A` is contained by list `B` (`A` is a sublist of `B`); or\n- None of the above is true, thus lists `A` and `B` are unequal\n\nSpecifically, list `A` is equal to list `B` if both lists have the same values in the same order.\nList `A` is a superlist of `B` if `A` contains a contiguous sub-sequence of values equal to `B`.\nList `A` is a sublist of `B` if `B` contains a contiguous sub-sequence of values equal to `A`.\n\nExamples:\n\n- If `A = []` and `B = []` (both lists are empty), then `A` and `B` are equal\n- If `A = [1, 2, 3]` and `B = []`, then `A` is a superlist of `B`\n- If `A = []` and `B = [1, 2, 3]`, then `A` is a sublist of `B`\n- If `A = [1, 2, 3]` and `B = [1, 2, 3, 4, 5]`, then `A` is a sublist of `B`\n- If `A = [3, 4, 5]` and `B = [1, 2, 3, 4, 5]`, then `A` is a sublist of `B`\n- If `A = [3, 4]` and `B = [1, 2, 3, 4, 5]`, then `A` is a sublist of `B`\n- If `A = [1, 2, 3]` and `B = [1, 2, 3]`, then `A` and `B` are equal\n- If `A = [1, 2, 3, 4, 5]` and `B = [2, 3, 4]`, then `A` is a superlist of `B`\n- If `A = [1, 2, 4]` and `B = [1, 2, 3, 4, 5]`, then `A` and `B` are unequal\n- If `A = [1, 2, 3]` and `B = [1, 3, 2]`, then `A` and `B` are unequal\n"
  },
  {
    "path": "exercises/practice/sublist/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"stkent\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Sublist.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/SublistTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Sublist.kt\"\n    ]\n  },\n  \"blurb\": \"Write a function to determine if a list is a sublist of another list.\"\n}\n"
  },
  {
    "path": "exercises/practice/sublist/.meta/src/reference/kotlin/Relationship.kt",
    "content": "enum class Relationship {\n\n    EQUAL, SUBLIST, SUPERLIST, UNEQUAL\n\n}\n"
  },
  {
    "path": "exercises/practice/sublist/.meta/src/reference/kotlin/Sublist.kt",
    "content": "fun <T> List<T>.relationshipTo(list: List<T>): Relationship {\n    if (this == list)         return Relationship.EQUAL\n    if (this.isSublist(list)) return Relationship.SUBLIST\n    if (list.isSublist(this)) return Relationship.SUPERLIST\n\n    return Relationship.UNEQUAL\n}\n\nprivate fun <T> List<T>.isSublist(list: List<T>): Boolean {\n    val listSize = list.size\n\n    if (size > listSize) return false\n\n    val numberOfSublistCandidates = listSize - size + 1\n\n    return (0 until numberOfSublistCandidates).any { startIndex ->\n        list.subList(startIndex, startIndex + size) == this\n    }\n}\n"
  },
  {
    "path": "exercises/practice/sublist/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# empty lists\n\"97319c93-ebc5-47ab-a022-02a1980e1d29\" = true\n\n# empty list within non empty list\n\"de27dbd4-df52-46fe-a336-30be58457382\" = true\n\n# non empty list contains empty list\n\"5487cfd1-bc7d-429f-ac6f-1177b857d4fb\" = true\n\n# list equals itself\n\"1f390b47-f6b2-4a93-bc23-858ba5dda9a6\" = true\n\n# different lists\n\"7ed2bfb2-922b-4363-ae75-f3a05e8274f5\" = true\n\n# false start\n\"3b8a2568-6144-4f06-b0a1-9d266b365341\" = true\n\n# consecutive\n\"dc39ed58-6311-4814-be30-05a64bc8d9b1\" = true\n\n# sublist at start\n\"d1270dab-a1ce-41aa-b29d-b3257241ac26\" = true\n\n# sublist in middle\n\"81f3d3f7-4f25-4ada-bcdc-897c403de1b6\" = true\n\n# sublist at end\n\"43bcae1e-a9cf-470e-923e-0946e04d8fdd\" = true\n\n# at start of superlist\n\"76cf99ed-0ff0-4b00-94af-4dfb43fe5caa\" = true\n\n# in middle of superlist\n\"b83989ec-8bdf-4655-95aa-9f38f3e357fd\" = true\n\n# at end of superlist\n\"26f9f7c3-6cf6-4610-984a-662f71f8689b\" = true\n\n# first list missing element from second list\n\"0a6db763-3588-416a-8f47-76b1cedde31e\" = true\n\n# second list missing element from first list\n\"83ffe6d8-a445-4a3c-8795-1e51a95e65c3\" = true\n\n# order matters to a list\n\"0d7ee7c1-0347-45c8-9ef5-b88db152b30b\" = true\n\n# same digits but different numbers\n\"5f47ce86-944e-40f9-9f31-6368aad70aa6\" = true\n"
  },
  {
    "path": "exercises/practice/sublist/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/sublist/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/sublist/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/sublist/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/sublist/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/sublist/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/sublist/src/main/kotlin/Sublist.kt",
    "content": "enum class Relationship {\n\n    EQUAL, SUBLIST, SUPERLIST, UNEQUAL\n\n}\n"
  },
  {
    "path": "exercises/practice/sublist/src/test/kotlin/SublistTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass SublistTest {\n\n    @Test\n    fun testThatTwoEmptyListsAreConsideredEqual() {\n        assertEquals(\n                Relationship.EQUAL,\n                emptyList<String>().relationshipTo(emptyList<String>()))\n    }\n\n    @Ignore\n    @Test\n    fun testEmptyListIsSublistOfNonEmptyList() {\n        assertEquals(\n                Relationship.SUBLIST,\n                emptyList<Int>().relationshipTo(listOf(1, 2, 3)))\n    }\n\n    @Ignore\n    @Test\n    fun testNonEmptyListIsSuperlistOfEmptyList() {\n        assertEquals(\n                Relationship.SUPERLIST,\n                listOf('1', '2', '3').relationshipTo(emptyList()))\n    }\n\n    @Ignore\n    @Test\n    fun testListIsEqualToItself() {\n        val anyList = listOf(\"1\", \"2\", \"3\")\n\n        assertEquals(\n                Relationship.EQUAL,\n                anyList.relationshipTo(anyList))\n    }\n\n    @Ignore\n    @Test\n    fun testDifferentListsOfTheSameLengthAreUnequal() {\n        assertEquals(\n                Relationship.UNEQUAL,\n                listOf(1, 2, 3).relationshipTo(listOf(2, 3, 4)))\n    }\n\n    @Ignore\n    @Test\n    fun testSublistCheckDoesNotAbortAfterFalseStart() {\n        assertEquals(\n                Relationship.SUBLIST,\n                listOf('1', '2', '5').relationshipTo(listOf('0', '1', '2', '3', '1', '2', '5', '6')))\n    }\n\n    @Ignore\n    @Test\n    fun testSublistCheckHandlesExtraneousRepeatsOfFirstEntry() {\n        assertEquals(\n                Relationship.SUBLIST,\n                listOf(\"1\", \"1\", \"2\").relationshipTo(listOf(\"0\", \"1\", \"1\", \"1\", \"2\", \"1\", \"2\")))\n    }\n\n    @Ignore\n    @Test\n    fun testSublistAtStart() {\n        assertEquals(\n                Relationship.SUBLIST,\n                listOf(0, 1, 2).relationshipTo(listOf(0, 1, 2, 3, 4, 5)))\n    }\n\n    @Ignore\n    @Test\n    fun testSublistInMiddle() {\n        assertEquals(\n                Relationship.SUBLIST,\n                listOf('2', '3', '4').relationshipTo(listOf('0', '1', '2', '3', '4', '5')))\n    }\n\n    @Ignore\n    @Test\n    fun testSublistAtEnd() {\n        assertEquals(\n                Relationship.SUBLIST,\n                listOf(\"3\", \"4\", \"5\").relationshipTo(listOf(\"0\", \"1\", \"2\", \"3\", \"4\", \"5\")))\n    }\n\n    @Ignore\n    @Test\n    fun testAtStartOfSuperlist() {\n        assertEquals(\n                Relationship.SUPERLIST,\n                listOf(0, 1, 2, 3, 4, 5).relationshipTo(listOf(0, 1, 2)))\n    }\n\n    @Ignore\n    @Test\n    fun testInMiddleOfSuperlist() {\n        assertEquals(\n                Relationship.SUPERLIST,\n                listOf('0', '1', '2', '3', '4', '5').relationshipTo(listOf('2', '3')))\n    }\n\n    @Ignore\n    @Test\n    fun testAtEndOfSuperlist() {\n        assertEquals(\n                Relationship.SUPERLIST,\n                listOf(\"0\", \"1\", \"2\", \"3\", \"4\", \"5\").relationshipTo(listOf(\"3\", \"4\", \"5\")))\n    }\n\n    @Ignore\n    @Test\n    fun testFirstListMissingElementFromSecondList() {\n        assertEquals(\n                Relationship.UNEQUAL,\n                listOf(1, 3).relationshipTo(listOf(1, 2, 3)))\n    }\n\n    @Ignore\n    @Test\n    fun testSecondListMissingElementFromFirstList() {\n        assertEquals(\n                Relationship.UNEQUAL,\n                listOf('1', '2', '3').relationshipTo(listOf('1', '3')))\n    }\n\n    @Ignore\n    @Test\n    fun testThatListOrderingIsAccountedFor() {\n        assertEquals(\n                Relationship.UNEQUAL,\n                listOf(\"1\", \"2\", \"3\").relationshipTo(listOf(\"3\", \"2\", \"1\")))\n    }\n\n    @Ignore\n    @Test\n    fun testThatListsWithSameDigitsButDifferentNumbersAreUnequal() {\n        assertEquals(\n                Relationship.UNEQUAL,\n                listOf(1, 0, 1).relationshipTo(listOf(10, 1)))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/sum-of-multiples/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to write the code that calculates the energy points that get awarded to players when they complete a level.\n\nThe points awarded depend on two things:\n\n- The level (a number) that the player completed.\n- The base value of each magical item collected by the player during that level.\n\nThe energy points are awarded according to the following rules:\n\n1. For each magical item, take the base value and find all the multiples of that value that are less than the level number.\n2. Combine the sets of numbers.\n3. Remove any duplicates.\n4. Calculate the sum of all the numbers that are left.\n\nLet's look at an example:\n\n**The player completed level 20 and found two magical items with base values of 3 and 5.**\n\nTo calculate the energy points earned by the player, we need to find all the unique multiples of these base values that are less than level 20.\n\n- Multiples of 3 less than 20: `{3, 6, 9, 12, 15, 18}`\n- Multiples of 5 less than 20: `{5, 10, 15}`\n- Combine the sets and remove duplicates: `{3, 5, 6, 9, 10, 12, 15, 18}`\n- Sum the unique multiples: `3 + 5 + 6 + 9 + 10 + 12 + 15 + 18 = 78`\n- Therefore, the player earns **78** energy points for completing level 20 and finding the two magical items with base values of 3 and 5.\n"
  },
  {
    "path": "exercises/practice/sum-of-multiples/.docs/introduction.md",
    "content": "# Introduction\n\nYou work for a company that makes an online, fantasy-survival game.\n\nWhen a player finishes a level, they are awarded energy points.\nThe amount of energy awarded depends on which magical items the player found while exploring that level.\n"
  },
  {
    "path": "exercises/practice/sum-of-multiples/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"nithia\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/SumOfMultiples.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/SumOfMultiplesTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/SumOfMultiples.kt\"\n    ]\n  },\n  \"blurb\": \"Given a number, find the sum of all the multiples of particular numbers up to but not including that number.\",\n  \"source\": \"A variation on Problem 1 at Project Euler\",\n  \"source_url\": \"https://projecteuler.net/problem=1\"\n}\n"
  },
  {
    "path": "exercises/practice/sum-of-multiples/.meta/src/reference/kotlin/SumOfMultiples.kt",
    "content": "object SumOfMultiples {\n\n    fun sum(factors: Set<Int>, limit: Int) =\n            with(factors.filter { it != 0 }) {\n                (1 until limit).filter { x -> any { y -> x.isMultipleOf(y) } }.sum()\n            }\n}\n\nfun Int.isMultipleOf(y: Int) = this % y == 0\n"
  },
  {
    "path": "exercises/practice/sum-of-multiples/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# no multiples within limit\n\"54aaab5a-ce86-4edc-8b40-d3ab2400a279\" = true\n\n# one factor has multiples within limit\n\"361e4e50-c89b-4f60-95ef-5bc5c595490a\" = true\n\n# more than one multiple within limit\n\"e644e070-040e-4ae0-9910-93c69fc3f7ce\" = true\n\n# more than one factor with multiples within limit\n\"607d6eb9-535c-41ce-91b5-3a61da3fa57f\" = true\n\n# each multiple is only counted once\n\"f47e8209-c0c5-4786-b07b-dc273bf86b9b\" = true\n\n# a much larger limit\n\"28c4b267-c980-4054-93e9-07723db615ac\" = true\n\n# three factors\n\"09c4494d-ff2d-4e0f-8421-f5532821ee12\" = true\n\n# factors not relatively prime\n\"2d0d5faa-f177-4ad6-bde9-ebb865083751\" = true\n\n# some pairs of factors relatively prime and some not\n\"ece8f2e8-96aa-4166-bbb7-6ce71261e354\" = true\n\n# one factor is a multiple of another\n\"624fdade-6ffb-400e-8472-456a38c171c0\" = true\n\n# much larger factors\n\"949ee7eb-db51-479c-b5cb-4a22b40ac057\" = true\n\n# all numbers are multiples of 1\n\"41093673-acbd-482c-ab80-d00a0cbedecd\" = true\n\n# no factors means an empty sum\n\"1730453b-baaa-438e-a9c2-d754497b2a76\" = true\n\n# the only multiple of 0 is 0\n\"214a01e9-f4bf-45bb-80f1-1dce9fbb0310\" = true\n\n# the factor 0 does not affect the sum of multiples of other factors\n\"c423ae21-a0cb-4ec7-aeb1-32971af5b510\" = true\n\n# solutions using include-exclude must extend to cardinality greater than 3\n\"17053ba9-112f-4ac0-aadb-0519dd836342\" = true\n"
  },
  {
    "path": "exercises/practice/sum-of-multiples/.meta/version",
    "content": "1.5.0\n"
  },
  {
    "path": "exercises/practice/sum-of-multiples/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/sum-of-multiples/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/sum-of-multiples/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/sum-of-multiples/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/sum-of-multiples/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/sum-of-multiples/src/main/kotlin/SumOfMultiples.kt",
    "content": "object SumOfMultiples {\n\n    fun sum(factors: Set<Int>, limit: Int): Int {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/sum-of-multiples/src/test/kotlin/SumOfMultiplesTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass SumOfMultiplesTest {\n    @Test\n    fun `no multiples within limit`() =\n            assertEquals(0, SumOfMultiples.sum(setOf(3, 5), 1))\n\n    @Test\n    @Ignore\n    fun `one factor has multiples within limit`() =\n            assertEquals(3, SumOfMultiples.sum(setOf(3, 5), 4))\n\n    @Test\n    @Ignore\n    fun `more than one multiple within limit`() =\n            assertEquals(9, SumOfMultiples.sum(setOf(3), 7))\n\n    @Test\n    @Ignore\n    fun `more than one factor with multiples within limit`() =\n            assertEquals(23, SumOfMultiples.sum(setOf(3, 5), 10))\n\n    @Test\n    @Ignore\n    fun `each multiple is only counted once`() =\n            assertEquals(2318, SumOfMultiples.sum(setOf(3, 5), 100))\n\n    @Test\n    @Ignore\n    fun `much larger limit`() =\n            assertEquals(233168, SumOfMultiples.sum(setOf(3, 5), 1000))\n\n    @Test\n    @Ignore\n    fun `three factors`() =\n            assertEquals(51, SumOfMultiples.sum(setOf(7, 13, 17), 20))\n\n    @Test\n    @Ignore\n    fun `factors not relatively prime`() =\n            assertEquals(30, SumOfMultiples.sum(setOf(4, 6), 15))\n\n    @Test\n    @Ignore\n    fun `some pairs of factors relatively prime and some not`() =\n            assertEquals(4419, SumOfMultiples.sum(setOf(5, 6, 8), 150))\n\n    @Test\n    @Ignore\n    fun `one factor is a multiple of another`() =\n            assertEquals(275, SumOfMultiples.sum(setOf(5, 25), 51))\n\n    @Test\n    @Ignore\n    fun `much larger factors`() =\n            assertEquals(2203160, SumOfMultiples.sum(setOf(43, 47), 10000))\n\n    @Test\n    @Ignore\n    fun `all numbers are multiples of 1`() =\n            assertEquals(4950, SumOfMultiples.sum(setOf(1), 100))\n\n    @Test\n    @Ignore\n    fun `no factors means an empty sum`() =\n            assertEquals(0, SumOfMultiples.sum(emptySet(), 10000))\n\n    @Test\n    @Ignore\n    fun `the only multiple of 0 is 0`() =\n            assertEquals(0, SumOfMultiples.sum(setOf(1), 1))\n\n    @Test\n    @Ignore\n    fun `the factor 0 does not affect the sum of multiples of other factors`() =\n            assertEquals(3, SumOfMultiples.sum(setOf(3, 0), 4))\n\n    @Test\n    @Ignore\n    fun `include-exclude-based solutions must extend to cardinality greater than 3`() =\n            assertEquals(39614537, SumOfMultiples.sum(setOf(2, 3, 5, 7, 11), 10000))\n}\n"
  },
  {
    "path": "exercises/practice/transpose/.docs/instructions.md",
    "content": "# Instructions\n\nGiven an input text output it transposed.\n\nRoughly explained, the transpose of a matrix:\n\n```text\nABC\nDEF\n```\n\nis given by:\n\n```text\nAD\nBE\nCF\n```\n\nRows become columns and columns become rows.\nSee [transpose][].\n\nIf the input has rows of different lengths, this is to be solved as follows:\n\n- Pad to the left with spaces.\n- Don't pad to the right.\n\nTherefore, transposing this matrix:\n\n```text\nABC\nDE\n```\n\nresults in:\n\n```text\nAD\nBE\nC\n```\n\nAnd transposing:\n\n```text\nAB\nDEF\n```\n\nresults in:\n\n```text\nAD\nBE\n F\n```\n\nIn general, all characters from the input should also be present in the transposed output.\nThat means that if a column in the input text contains only spaces on its bottom-most row(s), the corresponding output row should contain the spaces in its right-most column(s).\n\n[transpose]: https://en.wikipedia.org/wiki/Transpose\n"
  },
  {
    "path": "exercises/practice/transpose/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Transpose.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/TransposeTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Transpose.kt\"\n    ]\n  },\n  \"blurb\": \"Take input text and output it transposed.\",\n  \"source\": \"Reddit r/dailyprogrammer challenge #270 [Easy].\",\n  \"source_url\": \"https://web.archive.org/web/20230630051421/https://old.reddit.com/r/dailyprogrammer/comments/4msu2x/challenge_270_easy_transpose_the_input_text/\"\n}\n"
  },
  {
    "path": "exercises/practice/transpose/.meta/src/reference/kotlin/Transpose.kt",
    "content": "object Transpose {\n\n    fun transpose(input: List<String>): List<String> =\n            (0 until (input.map { it.length }.maxOrNull() ?: 0)).map { x: Int ->\n                input.indices.joinToString(\"\") { y: Int ->\n                    if (x < input[y].length) {\n                        input[y][x].toString()\n                    } else {\n                        \"°\"\n                    }\n                }.trimEnd('°').replace('°', ' ')\n            }\n}\n"
  },
  {
    "path": "exercises/practice/transpose/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# empty string\n\"404b7262-c050-4df0-a2a2-0cb06cd6a821\" = true\n\n# two characters in a row\n\"a89ce8a3-c940-4703-a688-3ea39412fbcb\" = true\n\n# two characters in a column\n\"855bb6ae-4180-457c-abd0-ce489803ce98\" = true\n\n# simple\n\"5ceda1c0-f940-441c-a244-0ced197769c8\" = true\n\n# single line\n\"a54675dd-ae7d-4a58-a9c4-0c20e99a7c1f\" = true\n\n# first line longer than second line\n\"0dc2ec0b-549d-4047-aeeb-8029fec8d5c5\" = true\n\n# second line longer than first line\n\"984e2ec3-b3d3-4b53-8bd6-96f5ef404102\" = true\n\n# mixed line length\n\"eccd3784-45f0-4a3f-865a-360cb323d314\" = true\n\n# square\n\"85b96b3f-d00c-4f80-8ca2-c8a5c9216c2d\" = true\n\n# rectangle\n\"b9257625-7a53-4748-8863-e08e9d27071d\" = true\n\n# triangle\n\"b80badc9-057e-4543-bd07-ce1296a1ea2c\" = true\n"
  },
  {
    "path": "exercises/practice/transpose/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/transpose/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/transpose/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/transpose/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/transpose/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/transpose/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/transpose/src/main/kotlin/Transpose.kt",
    "content": "object Transpose {\n\n    fun transpose(input: List<String>): List<String> {\n        TODO(\"Implement this to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/transpose/src/test/kotlin/TransposeTest.kt",
    "content": "import kotlin.test.Ignore\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\n\nclass TransposeTest {\n\n    @Test\n    fun `empty string`() {\n        val lines = listOf<String>()\n        val expected = listOf<String>()\n        assertEquals(expected, Transpose.transpose(lines))\n    }\n\n    @Ignore\n    @Test\n    fun `two characters in a row`() {\n        val lines = listOf(\"A1\")\n        val expected = listOf(\"A\", \"1\")\n        assertEquals(expected, Transpose.transpose(lines))\n    }\n\n    @Ignore\n    @Test\n    fun `two characters in a column`() {\n        val lines = listOf(\"A\", \"1\")\n        val expected = listOf(\"A1\")\n        assertEquals(expected, Transpose.transpose(lines))\n    }\n\n    @Ignore\n    @Test\n    fun simple() {\n        val lines = listOf(\"ABC\", \"123\")\n        val expected = listOf(\"A1\", \"B2\", \"C3\")\n        assertEquals(expected, Transpose.transpose(lines))\n    }\n\n    @Ignore\n    @Test\n    fun `single line`() {\n        val lines = listOf(\"Single line.\")\n        val expected = listOf(\"S\", \"i\", \"n\", \"g\", \"l\", \"e\", \" \", \"l\", \"i\", \"n\", \"e\", \".\")\n        assertEquals(expected, Transpose.transpose(lines))\n    }\n\n    @Ignore\n    @Test\n    fun `first line longer than second line`() {\n        val lines = listOf(\"The fourth line.\", \"The fifth line.\")\n        val expected = listOf(\"TT\", \"hh\", \"ee\", \"  \", \"ff\", \"oi\", \"uf\", \"rt\", \"th\", \"h \", \" l\", \"li\", \"in\", \"ne\", \"e.\", \".\")\n        assertEquals(expected, Transpose.transpose(lines))\n    }\n\n    @Ignore\n    @Test\n    fun `second line longer than first line`() {\n        val lines = listOf(\"The first line.\", \"The second line.\")\n        val expected = listOf(\"TT\", \"hh\", \"ee\", \"  \", \"fs\", \"ie\", \"rc\", \"so\", \"tn\", \" d\", \"l \", \"il\", \"ni\", \"en\", \".e\", \" .\")\n        assertEquals(expected, Transpose.transpose(lines))\n    }\n\n    @Ignore\n    @Test\n    fun `mixed line length`() {\n        val lines = listOf(\"The longest line.\", \"A long line.\", \"A longer line.\", \"A line.\")\n        val expected = listOf(\"TAAA\", \"h   \", \"elll\", \" ooi\", \"lnnn\", \"ogge\", \"n e.\", \"glr\", \"ei \", \"snl\", \"tei\", \" .n\", \"l e\", \"i .\", \"n\", \"e\", \".\")\n        assertEquals(expected, Transpose.transpose(lines))\n    }\n\n    @Ignore\n    @Test\n    fun square() {\n        val lines = listOf(\"HEART\", \"EMBER\", \"ABUSE\", \"RESIN\", \"TREND\")\n        val expected = listOf(\"HEART\", \"EMBER\", \"ABUSE\", \"RESIN\", \"TREND\")\n        assertEquals(expected, Transpose.transpose(lines))\n    }\n\n    @Ignore\n    @Test\n    fun rectangle() {\n        val lines = listOf(\"FRACTURE\", \"OUTLINED\", \"BLOOMING\", \"SEPTETTE\")\n        val expected = listOf(\"FOBS\", \"RULE\", \"ATOP\", \"CLOT\", \"TIME\", \"UNIT\", \"RENT\", \"EDGE\")\n        assertEquals(expected, Transpose.transpose(lines))\n    }\n\n    @Ignore\n    @Test\n    fun triangle() {\n        val lines = listOf(\"T\", \"EE\", \"AAA\", \"SSSS\", \"EEEEE\", \"RRRRRR\")\n        val expected = listOf(\"TEASER\", \" EASER\", \"  ASER\", \"   SER\", \"    ER\", \"     R\")\n        assertEquals(expected, Transpose.transpose(lines))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/triangle/.docs/instructions.md",
    "content": "# Instructions\n\nDetermine if a triangle is equilateral, isosceles, or scalene.\n\nAn _equilateral_ triangle has all three sides the same length.\n\nAn _isosceles_ triangle has at least two sides the same length.\n(It is sometimes specified as having exactly two sides the same length, but for the purposes of this exercise we'll say at least two.)\n\nA _scalene_ triangle has all sides of different lengths.\n\n## Note\n\nFor a shape to be a triangle at all, all sides have to be of length > 0, and the sum of the lengths of any two sides must be greater than or equal to the length of the third side.\n\nIn equations:\n\nLet `a`, `b`, and `c` be sides of the triangle.\nThen all three of the following expressions must be true:\n\n```text\na + b ≥ c\nb + c ≥ a\na + c ≥ b\n```\n\nSee [Triangle Inequality][triangle-inequality]\n\n[triangle-inequality]: https://en.wikipedia.org/wiki/Triangle_inequality\n"
  },
  {
    "path": "exercises/practice/triangle/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"nithia\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sdavids13\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Triangle.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/TriangleTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Triangle.kt\"\n    ]\n  },\n  \"blurb\": \"Determine if a triangle is equilateral, isosceles, or scalene.\",\n  \"source\": \"The Ruby Koans triangle project, parts 1 & 2\",\n  \"source_url\": \"https://web.archive.org/web/20220831105330/http://rubykoans.com\"\n}\n"
  },
  {
    "path": "exercises/practice/triangle/.meta/src/reference/kotlin/Triangle.kt",
    "content": "class Triangle<out T: Number>(val a: T, val b: T, val c: T) {\n\n    init {\n        require(a > 0 && b > 0 && c > 0) { \"Sides must be > 0\" }\n        require(a + b >= c && b + c >= a && c + a >= b) { \"Sides must satisfy triangle inequality\" }\n    }\n\n    val isEquilateral = a == b && b == c\n    val isIsosceles = a == b || b == c || c == a\n    val isScalene = !isIsosceles\n\n    private infix operator fun <T: Number> T.compareTo(other: T): Int = this.toDouble().compareTo(other.toDouble())\n    private infix operator fun <T: Number> T.plus(b: T): Double = this.toDouble().plus(b.toDouble())\n\n}\n"
  },
  {
    "path": "exercises/practice/triangle/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# all sides are equal\n\"8b2c43ac-7257-43f9-b552-7631a91988af\" = true\n\n# any side is unequal\n\"33eb6f87-0498-4ccf-9573-7f8c3ce92b7b\" = true\n\n# no sides are equal\n\"c6585b7d-a8c0-4ad8-8a34-e21d36f7ad87\" = true\n\n# all zero sides is not a triangle\n\"16e8ceb0-eadb-46d1-b892-c50327479251\" = true\n\n# sides may be floats\n\"3022f537-b8e5-4cc1-8f12-fd775827a00c\" = true\n\n# last two sides are equal\n\"cbc612dc-d75a-4c1c-87fc-e2d5edd70b71\" = true\n\n# first two sides are equal\n\"e388ce93-f25e-4daf-b977-4b7ede992217\" = true\n\n# first and last sides are equal\n\"d2080b79-4523-4c3f-9d42-2da6e81ab30f\" = true\n\n# equilateral triangles are also isosceles\n\"8d71e185-2bd7-4841-b7e1-71689a5491d8\" = true\n\n# no sides are equal\n\"840ed5f8-366f-43c5-ac69-8f05e6f10bbb\" = true\n\n# first triangle inequality violation\n\"2eba0cfb-6c65-4c40-8146-30b608905eae\" = true\n\n# second triangle inequality violation\n\"278469cb-ac6b-41f0-81d4-66d9b828f8ac\" = true\n\n# third triangle inequality violation\n\"90efb0c7-72bb-4514-b320-3a3892e278ff\" = true\n\n# sides may be floats\n\"adb4ee20-532f-43dc-8d31-e9271b7ef2bc\" = true\n\n# no sides are equal\n\"e8b5f09c-ec2e-47c1-abec-f35095733afb\" = true\n\n# all sides are equal\n\"2510001f-b44d-4d18-9872-2303e7977dc1\" = true\n\n# two sides are equal\n\"c6e15a92-90d9-4fb3-90a2-eef64f8d3e1e\" = true\n\n# may not violate triangle inequality\n\"70ad5154-0033-48b7-af2c-b8d739cd9fdc\" = true\n\n# sides may be floats\n\"26d9d59d-f8f1-40d3-ad58-ae4d54123d7d\" = true\n"
  },
  {
    "path": "exercises/practice/triangle/.meta/version",
    "content": "1.2.1\n"
  },
  {
    "path": "exercises/practice/triangle/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/triangle/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/triangle/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/triangle/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/triangle/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/triangle/src/main/kotlin/Triangle.kt",
    "content": "class Triangle<out T : Number>(val a: T, val b: T, val c: T) {\n\n    // TODO: Implement proper constructor\n\n    val isEquilateral: Boolean = TODO(\"Implement this getter to complete the task\")\n    val isIsosceles: Boolean = TODO(\"Implement this getter to complete the task\")\n    val isScalene: Boolean = TODO(\"Implement this getter to complete the task\")\n}\n"
  },
  {
    "path": "exercises/practice/triangle/src/test/kotlin/TriangleTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertFalse\nimport kotlin.test.assertTrue\n\nclass TriangleTest {\n\n    @Test\n    fun `equilateral - all sides are equal`() {\n        assertTrue(Triangle(2, 2, 2).isEquilateral)\n    }\n\n    @Ignore\n    @Test\n    fun `equilateral - any side is unequal`() {\n        assertFalse(Triangle(2, 3, 2).isEquilateral)\n    }\n\n    @Ignore\n    @Test\n    fun `equilateral - no sides are equal`() {\n        assertFalse(Triangle(5, 4, 6).isEquilateral)\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `equilateral - all zero sides is not a triangle`() {\n        assertFalse(Triangle(0, 0, 0).isEquilateral)\n    }\n\n    @Ignore\n    @Test\n    fun `equilateral - sides may be floats`() {\n        assertTrue(Triangle(0.5, 0.5, 0.5).isEquilateral)\n    }\n\n    @Ignore\n    @Test\n    fun `isosceles - last two sides are equal`() {\n        assertTrue(Triangle(3, 4, 4).isIsosceles)\n    }\n\n    @Ignore\n    @Test\n    fun `isosceles - first two sides are equal`() {\n        assertTrue(Triangle(4, 4, 3).isIsosceles)\n    }\n\n    @Ignore\n    @Test\n    fun `isosceles - first and last sides are equal`() {\n        assertTrue(Triangle(4, 3, 4).isIsosceles)\n    }\n\n    @Ignore\n    @Test\n    fun `isosceles - equilateral triangles are also isosceles`() {\n        assertTrue(Triangle(4, 4, 4).isIsosceles)\n    }\n\n    @Ignore\n    @Test\n    fun `isosceles - no sides are equal`() {\n        assertFalse(Triangle(2, 3, 4).isIsosceles)\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `triangle inequality violation - last is greater then sum of others `() {\n        Triangle(1, 1, 3)\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `triangle inequality violation - second is greater then sum of others `() {\n        Triangle(1, 3, 1)\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `triangle inequality violation - first is greater then sum of others `() {\n        Triangle(3, 1, 1)\n    }\n\n    @Ignore\n    @Test\n    fun `isosceles - sides may be floats`() {\n        assertTrue(Triangle(0.5, 0.4, 0.5).isIsosceles)\n    }\n\n    @Ignore\n    @Test\n    fun `scalene - no sides are equal`() {\n        assertTrue(Triangle(5, 4, 6).isScalene)\n    }\n\n    @Ignore\n    @Test\n    fun `scalene - all sides are equal`() {\n        assertFalse(Triangle(4, 4, 4).isScalene)\n    }\n\n    @Ignore\n    @Test\n    fun `scalene - two sides are equal`() {\n        assertFalse(Triangle(4, 4, 3).isScalene)\n    }\n\n    @Ignore\n    @Test(expected = IllegalArgumentException::class)\n    fun `scalene - may not violate triangle inequality`() {\n        Triangle(7, 3, 2)\n    }\n\n    @Ignore\n    @Test\n    fun `scalene - sides may be floats`() {\n        assertTrue(Triangle(0.5, 0.4, 0.6).isScalene)\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/two-fer/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to determine what you will say as you give away the extra cookie.\n\nIf you know the person's name (e.g. if they're named Do-yun), then you will say:\n\n```text\nOne for Do-yun, one for me.\n```\n\nIf you don't know the person's name, you will say _you_ instead.\n\n```text\nOne for you, one for me.\n```\n\nHere are some examples:\n\n| Name   | Dialogue                    |\n| :----- | :-------------------------- |\n| Alice  | One for Alice, one for me.  |\n| Bohdan | One for Bohdan, one for me. |\n|        | One for you, one for me.    |\n| Zaphod | One for Zaphod, one for me. |\n"
  },
  {
    "path": "exercises/practice/two-fer/.docs/introduction.md",
    "content": "# Introduction\n\nIn some English accents, when you say \"two for\" quickly, it sounds like \"two fer\".\nTwo-for-one is a way of saying that if you buy one, you also get one for free.\nSo the phrase \"two-fer\" often implies a two-for-one offer.\n\nImagine a bakery that has a holiday offer where you can buy two cookies for the price of one (\"two-fer one!\").\nYou take the offer and (very generously) decide to give the extra cookie to someone else in the queue.\n"
  },
  {
    "path": "exercises/practice/two-fer/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"Mouzourides\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"lihofm\",\n    \"mdowds\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"sup95\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/TwoFer.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/TwoFerTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/TwoFer.kt\"\n    ]\n  },\n  \"blurb\": \"Create a sentence of the form \\\"One for X, one for me.\\\".\",\n  \"source_url\": \"https://github.com/exercism/problem-specifications/issues/757\"\n}\n"
  },
  {
    "path": "exercises/practice/two-fer/.meta/src/reference/kotlin/TwoFer.kt",
    "content": "fun twofer(name: String = \"you\"): String {\n    return \"One for $name, one for me.\"\n}"
  },
  {
    "path": "exercises/practice/two-fer/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# no name given\n\"1cf3e15a-a3d7-4a87-aeb3-ba1b43bc8dce\" = true\n\n# a name given\n\"b4c6dbb8-b4fb-42c2-bafd-10785abe7709\" = true\n\n# another name given\n\"3549048d-1a6e-4653-9a79-b0bda163e8d5\" = true\n"
  },
  {
    "path": "exercises/practice/two-fer/.meta/version",
    "content": "1.2.0\n"
  },
  {
    "path": "exercises/practice/two-fer/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/two-fer/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/two-fer/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/two-fer/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/two-fer/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/two-fer/src/main/kotlin/TwoFer.kt",
    "content": "fun twofer(name: String): String {\n    TODO(\"Implement the function to complete the task\")\n}\n"
  },
  {
    "path": "exercises/practice/two-fer/src/test/kotlin/TwoFerTest.kt",
    "content": "import org.junit.Ignore\nimport org.junit.Test\nimport kotlin.test.assertEquals\n\nclass TwoFerTest {\n\n    @Test\n    fun noNameGiven() {\n        assertEquals(\"One for you, one for me.\", twofer())\n    }\n\n    @Test\n    @Ignore\n    fun aNameGiven() {\n        assertEquals(\"One for Alice, one for me.\", twofer(\"Alice\"))\n    }\n\n    @Test\n    @Ignore\n    fun anotherNameGiven() {\n        assertEquals(\"One for Bob, one for me.\", twofer(\"Bob\"))\n    }\n\n    @Test\n    @Ignore\n    fun emptyStringGiven() {\n        assertEquals(\"One for , one for me.\", twofer(\"\"))\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/word-count/.approaches/config.json",
    "content": "{\n  \"introduction\": {\n    \"authors\": [\n      \"bobahop\"\n    ]\n  },\n  \"approaches\": [\n    {\n      \"uuid\": \"310ac3a8-5ef7-47c6-a2c9-5efc98a17d4a\",\n      \"slug\": \"findall-groupingby-eachcount\",\n      \"title\": \"findAll with groupingBy and eachCount\",\n      \"blurb\": \"Use findAll with groupingBy and eachCount to return the answer.\",\n      \"authors\": [\n        \"bobahop\"\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "exercises/practice/word-count/.approaches/findall-groupingby-eachcount/content.md",
    "content": "# `findAll` with `groupingBy` and `eachCount`\n\n```kotlin\nobject WordCount {\n\n    fun phrase(phrase: String): Map<String, Int> {\n        return Regex(\"[a-z0-9]+(?:'[a-z]+)?\")\n                .findAll(phrase.lowercase())\n                .groupingBy { it.value }\n                .eachCount()\n    }\n}\n```\n\nAn [object declaration][object] is used to define `WordCount` as essentially a [singleton][singleton] object instantiation of the class.\nThis is sufficient, since there is no object state that needs to change with each call of the `phrase` method.\n\nA [regular expression][regex] pattern is defined to match the characters expected to be found in the words.\nAt the time of writing, the valid characters are alphanumeric and the apostrophe.\nThe pattern looks for one or more alphanumeric characters (`[a-z0-9]+`), either followed by an apostrophe and one or more alphabetic characters,\nor not (`(?:'[a-z]+)?`). \n\nThe [`findAll`][findall] method is called on the `Regex` to match the words in the lowercased input to the pattern.\n\nThe found words are passed to the [`groupingBy`][groupingby] method.\nThe [lambda][lambda] of `groupingBy` uses the [`it`][it] keyword to refer to the single [`MatchResult`][matchresult] parameter for the lambda,\nand uses its [`value`][value] property for the value to be grouped by.\n\nEach group is then transformed into a `Map<String, int>` by the [`eachCount`][eachcount] method, which creates a key/value pair for each word and its frequency\nas an entry for the `Map`.\n\nFinally, the `Map` is returned by the function.\n\n[object]: https://kotlinlang.org/docs/object-declarations.html#object-declarations-overview\n[singleton]: https://en.wikipedia.org/wiki/Singleton_pattern\n[regex]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-regex/\n[findall]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-regex/find-all.html\n[groupingby]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/grouping-by.html\n[lambda]: https://kotlinlang.org/docs/lambdas.html#lambda-expressions-and-anonymous-functions\n[it]: https://kotlinlang.org/docs/lambdas.html#it-implicit-name-of-a-single-parameter\n[matchresult]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-match-result/\n[value]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-match-result/value.html\n[eachcount]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/each-count.html\n"
  },
  {
    "path": "exercises/practice/word-count/.approaches/findall-groupingby-eachcount/snippet.txt",
    "content": "object WordCount {\n    fun phrase(phrase: String): Map<String, Int> {\n        return Regex(\"[a-z0-9]+(?:'[a-z]+)?\")\n                .findAll(phrase.lowercase())\n                .groupingBy { it.value }\n                .eachCount()\n    }\n}\n"
  },
  {
    "path": "exercises/practice/word-count/.approaches/introduction.md",
    "content": "# Introduction\n\nThere are two main ways to solve Word Count.\nThere are many variants of splitting the words on a more or less complex pattern, and that usually filter out blank/empty values.\nAnother approach is to use a [regular expression][regex] pattern to find words.\n\n## Approach: `findAll` with `groupingBy` and `eachCount`\n\n```kotlin\nobject WordCount {\n\n    fun phrase(phrase: String): Map<String, Int> {\n        return Regex(\"[a-z0-9]+(?:'[a-z]+)?\")\n                .findAll(phrase.lowercase())\n                .groupingBy { it.value }\n                .eachCount()\n    }\n}\n```\n\nFor more information, check the [`findAll` with `groupingBy` and `eachCount` approach][approach-findall-groupingby-eachcount].\n\n[approach-findall-groupingby-eachcount]: https://exercism.org/tracks/kotlin/exercises/word-count/approaches/findall-groupingby-eachcount\n[regex]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-regex/\n"
  },
  {
    "path": "exercises/practice/word-count/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to count how many times each word occurs in a subtitle of a drama.\n\nThe subtitles from these dramas use only ASCII characters.\n\nThe characters often speak in casual English, using contractions like _they're_ or _it's_.\nThough these contractions come from two words (e.g. _we are_), the contraction (_we're_) is considered a single word.\n\nWords can be separated by any form of punctuation (e.g. \":\", \"!\", or \"?\") or whitespace (e.g. \"\\t\", \"\\n\", or \" \").\nThe only punctuation that does not separate words is the apostrophe in contractions.\n\nNumbers are considered words.\nIf the subtitles say _It costs 100 dollars._ then _100_ will be its own word.\n\nWords are case insensitive.\nFor example, the word _you_ occurs three times in the following sentence:\n\n> You come back, you hear me? DO YOU HEAR ME?\n\nThe ordering of the word counts in the results doesn't matter.\n\nHere's an example that incorporates several of the elements discussed above:\n\n- simple words\n- contractions\n- numbers\n- case insensitive words\n- punctuation (including apostrophes) to separate words\n- different forms of whitespace to separate words\n\n`\"That's the password: 'PASSWORD 123'!\", cried the Special Agent.\\nSo I fled.`\n\nThe mapping for this subtitle would be:\n\n```text\n123: 1\nagent: 1\ncried: 1\nfled: 1\ni: 1\npassword: 2\nso: 1\nspecial: 1\nthat's: 1\nthe: 2\n```\n"
  },
  {
    "path": "exercises/practice/word-count/.docs/introduction.md",
    "content": "# Introduction\n\nYou teach English as a foreign language to high school students.\n\nYou've decided to base your entire curriculum on TV shows.\nYou need to analyze which words are used, and how often they're repeated.\n\nThis will let you choose the simplest shows to start with, and to gradually increase the difficulty as time passes.\n"
  },
  {
    "path": "exercises/practice/word-count/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"sdavids13\"\n  ],\n  \"contributors\": [\n    \"dector\",\n    \"eparovyshnaya\",\n    \"jtigger\",\n    \"kytrinyx\",\n    \"lihofm\",\n    \"mdowds\",\n    \"nithia\",\n    \"sjwarner-bp\",\n    \"SleeplessByte\",\n    \"stkent\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/WordCount.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/WordCountTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/WordCount.kt\"\n    ]\n  },\n  \"blurb\": \"Given a phrase, count the occurrences of each word in that phrase.\",\n  \"source\": \"This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour.\"\n}\n"
  },
  {
    "path": "exercises/practice/word-count/.meta/src/reference/kotlin/WordCount.kt",
    "content": "object WordCount {\n\n    fun phrase(phrase: String): Map<String, Int> {\n        val withoutPunctuation = phrase.lowercase().replace(Regex(\"[^\\\\w']\"), \" \").trim()\n\n        val words = withoutPunctuation.split(Regex(\"\\\\s+\"))\n\n        val unquotedWords = words.map { word -> word.trim('\\'') }\n\n        val groupedWords = unquotedWords.groupBy { w -> w }\n\n        return groupedWords.mapValues { it.value.size }\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/word-count/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# count one word\n\"61559d5f-2cad-48fb-af53-d3973a9ee9ef\" = true\n\n# count one of each word\n\"5abd53a3-1aed-43a4-a15a-29f88c09cbbd\" = true\n\n# multiple occurrences of a word\n\"2a3091e5-952e-4099-9fac-8f85d9655c0e\" = true\n\n# handles cramped lists\n\"e81877ae-d4da-4af4-931c-d923cd621ca6\" = true\n\n# handles expanded lists\n\"7349f682-9707-47c0-a9af-be56e1e7ff30\" = true\n\n# ignore punctuation\n\"a514a0f2-8589-4279-8892-887f76a14c82\" = true\n\n# include numbers\n\"d2e5cee6-d2ec-497b-bdc9-3ebe092ce55e\" = true\n\n# normalize case\n\"dac6bc6a-21ae-4954-945d-d7f716392dbf\" = true\n\n# with apostrophes\n\"4185a902-bdb0-4074-864c-f416e42a0f19\" = true\n\n# with quotations\n\"be72af2b-8afe-4337-b151-b297202e4a7b\" = true\n\n# substrings from the beginning\n\"8d6815fe-8a51-4a65-96f9-2fb3f6dc6ed6\" = true\n\n# multiple spaces not detected as a word\n\"c5f4ef26-f3f7-4725-b314-855c04fb4c13\" = true\n\n# alternating word separators not detected as a word\n\"50176e8a-fe8e-4f4c-b6b6-aa9cf8f20360\" = true\n"
  },
  {
    "path": "exercises/practice/word-count/.meta/version",
    "content": "1.4.0\n"
  },
  {
    "path": "exercises/practice/word-count/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/word-count/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/word-count/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/word-count/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/word-count/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/word-count/src/main/kotlin/WordCount.kt",
    "content": "object WordCount {\n\n    fun phrase(phrase: String): Map<String, Int> {\n        TODO(\"Implement this function to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/word-count/src/test/kotlin/WordCountTest.kt",
    "content": "import org.junit.Test\nimport org.junit.Ignore\nimport kotlin.test.assertEquals\n\nclass WordCountTest {\n\n    @Test\n    fun `one word`() = assertWordCountEqual(\n        \"word\",\n        \"word\" to 1\n    )\n\n    @Ignore\n    @Test\n    fun `one of each word`() = assertWordCountEqual(\n        \"one of each\",\n        \"one\" to 1,\n        \"of\" to 1,\n        \"each\" to 1\n    )\n\n    @Ignore\n    @Test\n    fun `multiple occurrences of a word`() = assertWordCountEqual(\n        \"one fish two fish red fish blue fish\",\n        \"one\" to 1,\n        \"fish\" to 4,\n        \"two\" to 1,\n        \"red\" to 1,\n        \"blue\" to 1\n    )\n\n    @Ignore\n    @Test\n    fun `cramped list`() = assertWordCountEqual(\n        \"one,two,three\",\n        \"one\" to 1,\n        \"two\" to 1,\n        \"three\" to 1\n    )\n\n    @Ignore\n    @Test\n    fun `expanded list`() = assertWordCountEqual(\n        \"one,\\ntwo,\\nthree\",\n        \"one\" to 1,\n        \"two\" to 1,\n        \"three\" to 1\n    )\n\n    @Ignore\n    @Test\n    fun `punctuation is ignored`() = assertWordCountEqual(\n        \"car: carpet as java: javascript!!&@\\$%^&\",\n        \"car\" to 1,\n        \"carpet\" to 1,\n        \"as\" to 1,\n        \"java\" to 1,\n        \"javascript\" to 1\n    )\n\n    @Ignore\n    @Test\n    fun `numbers are allowed`() = assertWordCountEqual(\n        \"testing, 1, 2 testing\",\n        \"testing\" to 2,\n        \"1\" to 1,\n        \"2\" to 1\n    )\n\n    @Ignore\n    @Test\n    fun `case insensitive`() = assertWordCountEqual(\n        \"go Go GO Stop stop\",\n        \"go\" to 3,\n        \"stop\" to 2\n    )\n\n    @Ignore\n    @Test\n    fun `apostrophes are allowed`() = assertWordCountEqual(\n        \"First: don't laugh. Then: don't cry.\",\n        \"first\" to 1,\n        \"don't\" to 2,\n        \"laugh\" to 1,\n        \"then\" to 1,\n        \"cry\" to 1\n    )\n\n    @Ignore\n    @Test\n    fun `quotations are allowed`() = assertWordCountEqual(\n        \"Joe can't tell between 'large' and large.\",\n        \"joe\" to 1,\n        \"can't\" to 1,\n        \"tell\" to 1,\n        \"between\" to 1,\n        \"large\" to 2,\n        \"and\" to 1\n    )\n\n    @Ignore\n    @Test\n    fun `heading substring`() = assertWordCountEqual(\n        \"Joe can't tell between app, apple and a.\",\n        \"joe\" to 1,\n        \"can't\" to 1,\n        \"tell\" to 1,\n        \"between\" to 1,\n        \"app\" to 1,\n        \"apple\" to 1,\n        \"and\" to 1,\n        \"a\" to 1\n    )\n\n    @Ignore\n    @Test\n    fun `multiple spaces`() = assertWordCountEqual(\n        \" multiple   whitespaces\",\n        \"multiple\" to 1,\n        \"whitespaces\" to 1\n    )\n\n    @Ignore\n    @Test\n    fun `various separators`() =\n        assertWordCountEqual(\n            \",\\n,one,\\n ,two \\n 'three'\",\n            \"one\" to 1,\n            \"two\" to 1,\n            \"three\" to 1\n        )\n}\n\nprivate fun assertWordCountEqual(phrase: String, vararg expectations: Pair<String, Int>) =\n    assertEquals(expectations.toMap(), WordCount.phrase(phrase))\n"
  },
  {
    "path": "exercises/practice/wordy/.docs/instructions.md",
    "content": "# Instructions\n\nParse and evaluate simple math word problems returning the answer as an integer.\n\n## Iteration 0 — Numbers\n\nProblems with no operations simply evaluate to the number given.\n\n> What is 5?\n\nEvaluates to 5.\n\n## Iteration 1 — Addition\n\nAdd two numbers together.\n\n> What is 5 plus 13?\n\nEvaluates to 18.\n\nHandle large numbers and negative numbers.\n\n## Iteration 2 — Subtraction, Multiplication and Division\n\nNow, perform the other three operations.\n\n> What is 7 minus 5?\n\n2\n\n> What is 6 multiplied by 4?\n\n24\n\n> What is 25 divided by 5?\n\n5\n\n## Iteration 3 — Multiple Operations\n\nHandle a set of operations, in sequence.\n\nSince these are verbal word problems, evaluate the expression from left-to-right, _ignoring the typical order of operations._\n\n> What is 5 plus 13 plus 6?\n\n24\n\n> What is 3 plus 2 multiplied by 3?\n\n15 (i.e. not 9)\n\n## Iteration 4 — Errors\n\nThe parser should reject:\n\n- Unsupported operations (\"What is 52 cubed?\")\n- Non-math questions (\"Who is the President of the United States\")\n- Word problems with invalid syntax (\"What is 1 plus plus 2?\")\n"
  },
  {
    "path": "exercises/practice/wordy/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Wordy.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/WordyTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Wordy.kt\"\n    ]\n  },\n  \"blurb\": \"Parse and evaluate simple math word problems returning the answer as an integer.\",\n  \"source\": \"Inspired by one of the generated questions in the Extreme Startup game.\",\n  \"source_url\": \"https://github.com/rchatley/extreme_startup\"\n}\n"
  },
  {
    "path": "exercises/practice/wordy/.meta/src/reference/kotlin/Wordy.kt",
    "content": "import java.util.regex.Pattern\nimport kotlin.math.pow\n\nobject Wordy {\n\n    private val startPattern = Pattern.compile(\"^What is (-?\\\\d+)(.*)\\\\?$\")\n    private val operandPattern = Pattern.compile(\"^ ([^-0-9]+) (-?\\\\d+)(.*)$\")\n    private val powerPattern = Pattern.compile(\"^ raised to the (-?\\\\d+)(st|nd|rd|th) power(.*)$\")\n\n    fun answer(input: String): Int {\n        val startMatcher = startPattern.matcher(input)\n        require(startMatcher.find())\n        val firstNumber = startMatcher.group(1).toInt()\n        val rest = startMatcher.group(2)\n        return answerRecursive(rest, firstNumber)\n    }\n\n    private fun answerRecursive(input: String, result: Int): Int {\n        val operandMatcher = operandPattern.matcher(input)\n        val powerMatcher = powerPattern.matcher(input)\n        return when {\n            powerMatcher.find() -> {\n                val operand = powerMatcher.group(1).toInt()\n                val rest = powerMatcher.group(3)\n                answerRecursive(rest, result.toDouble().pow(operand.toDouble()).toInt())\n            }\n            operandMatcher.find() -> {\n                val operator = operandMatcher.group(1)\n                val operand = operandMatcher.group(2).toInt()\n                val rest = operandMatcher.group(3)\n                when (operator) {\n                    \"plus\" -> answerRecursive(rest, result + operand)\n                    \"minus\" -> answerRecursive(rest, result - operand)\n                    \"multiplied by\" -> answerRecursive(rest, result * operand)\n                    \"divided by\" -> answerRecursive(rest, result / operand)\n                    else -> throw IllegalArgumentException(\"Unknown operator '$operator'!\")\n                }\n            }\n            input.isEmpty() -> result\n            else -> throw IllegalArgumentException(\"Cannot parse '$input'!\")\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/wordy/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# just a number\n\"88bf4b28-0de3-4883-93c7-db1b14aa806e\" = true\n\n# addition\n\"bb8c655c-cf42-4dfc-90e0-152fcfd8d4e0\" = true\n\n# more addition\n\"79e49e06-c5ae-40aa-a352-7a3a01f70015\" = true\n\n# addition with negative numbers\n\"b345dbe0-f733-44e1-863c-5ae3568f3803\" = true\n\n# large addition\n\"cd070f39-c4cc-45c4-97fb-1be5e5846f87\" = true\n\n# subtraction\n\"0d86474a-cd93-4649-a4fa-f6109a011191\" = true\n\n# multiplication\n\"30bc8395-5500-4712-a0cf-1d788a529be5\" = true\n\n# division\n\"34c36b08-8605-4217-bb57-9a01472c427f\" = true\n\n# multiple additions\n\"da6d2ce4-fb94-4d26-8f5f-b078adad0596\" = true\n\n# addition and subtraction\n\"7fd74c50-9911-4597-be09-8de7f2fea2bb\" = true\n\n# multiple subtraction\n\"b120ffd5-bad6-4e22-81c8-5512e8faf905\" = true\n\n# subtraction then addition\n\"4f4a5749-ef0c-4f60-841f-abcfaf05d2ae\" = true\n\n# multiple multiplication\n\"312d908c-f68f-42c9-aa75-961623cc033f\" = true\n\n# addition and multiplication\n\"38e33587-8940-4cc1-bc28-bfd7e3966276\" = true\n\n# multiple division\n\"3c854f97-9311-46e8-b574-92b60d17d394\" = true\n\n# unknown operation\n\"3ad3e433-8af7-41ec-aa9b-97b42ab49357\" = true\n\n# Non math question\n\"8a7e85a8-9e7b-4d46-868f-6d759f4648f8\" = true\n\n# reject problem missing an operand\n\"42d78b5f-dbd7-4cdb-8b30-00f794bb24cf\" = true\n\n# reject problem with no operands or operators\n\"c2c3cbfc-1a72-42f2-b597-246e617e66f5\" = true\n\n# reject two operations in a row\n\"4b3df66d-6ed5-4c95-a0a1-d38891fbdab6\" = true\n\n# reject two numbers in a row\n\"6abd7a50-75b4-4665-aa33-2030fd08bab1\" = true\n\n# reject postfix notation\n\"10a56c22-e0aa-405f-b1d2-c642d9c4c9de\" = true\n\n# reject prefix notation\n\"0035bc63-ac43-4bb5-ad6d-e8651b7d954e\" = true\n"
  },
  {
    "path": "exercises/practice/wordy/.meta/version",
    "content": "1.5.0\n"
  },
  {
    "path": "exercises/practice/wordy/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/wordy/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/wordy/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/wordy/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/wordy/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/wordy/src/main/kotlin/Wordy.kt",
    "content": "object Wordy {\n\n    fun answer(input: String): Int {\n        TODO(\"Implement this to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/wordy/src/test/kotlin/WordyTest.kt",
    "content": "import kotlin.test.Ignore\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\n\nclass WordyTest {\n\n    @Test\n    fun `just a number`() = assertEquals(5, Wordy.answer(\"What is 5?\"))\n\n    @Ignore\n    @Test\n    fun addition() = assertEquals(2, Wordy.answer(\"What is 1 plus 1?\"))\n\n    @Ignore\n    @Test\n    fun `more addition`() = assertEquals(55, Wordy.answer(\"What is 53 plus 2?\"))\n\n    @Ignore\n    @Test\n    fun `addition with negative numbers`() = assertEquals(-11, Wordy.answer(\"What is -1 plus -10?\"))\n\n    @Ignore\n    @Test\n    fun `large addition`() = assertEquals(45801, Wordy.answer(\"What is 123 plus 45678?\"))\n\n    @Ignore\n    @Test\n    fun subtraction() = assertEquals(16, Wordy.answer(\"What is 4 minus -12?\"))\n\n    @Ignore\n    @Test\n    fun multiplication() = assertEquals(-75, Wordy.answer(\"What is -3 multiplied by 25?\"))\n\n    @Ignore\n    @Test\n    fun division() = assertEquals(-11, Wordy.answer(\"What is 33 divided by -3?\"))\n\n    @Ignore\n    @Test\n    fun `multiple additions`() = assertEquals(3, Wordy.answer(\"What is 1 plus 1 plus 1?\"))\n\n    @Ignore\n    @Test\n    fun `addition and subtraction`() = assertEquals(8, Wordy.answer(\"What is 1 plus 5 minus -2?\"))\n\n    @Ignore\n    @Test\n    fun `multiple subtraction`() = assertEquals(3, Wordy.answer(\"What is 20 minus 4 minus 13?\"))\n\n    @Ignore\n    @Test\n    fun `subtraction then addition`() = assertEquals(14, Wordy.answer(\"What is 17 minus 6 plus 3?\"))\n\n    @Ignore\n    @Test\n    fun `multiple multiplication`() = assertEquals(-12, Wordy.answer(\"What is 2 multiplied by -2 multiplied by 3?\"))\n\n    @Ignore\n    @Test\n    fun `addition and multiplication`() = assertEquals(-8, Wordy.answer(\"What is -3 plus 7 multiplied by -2?\"))\n\n    @Ignore\n    @Test\n    fun `multiple division`() = assertEquals(2, Wordy.answer(\"What is -12 divided by 2 divided by -3?\"))\n\n    @Ignore\n    @Test(expected = Exception::class)\n    fun `unknown operation`() = Wordy.answer(\"What is 52 cubed?\").toUnit()\n\n    @Ignore\n    @Test(expected = Exception::class)\n    fun `non math question`() = Wordy.answer(\"Who is the President of the United States?\").toUnit()\n\n    @Ignore\n    @Test(expected = Exception::class)\n    fun `reject problem missing an operand`() = Wordy.answer(\"What is 1 plus?\").toUnit()\n\n    @Ignore\n    @Test(expected = Exception::class)\n    fun `reject problem with no operands or operators`() = Wordy.answer(\"What is?\").toUnit()\n\n    @Ignore\n    @Test(expected = Exception::class)\n    fun `reject two operations in a row`() = Wordy.answer(\"What is 1 plus plus 2?\").toUnit()\n\n    @Ignore\n    @Test(expected = Exception::class)\n    fun `reject two numbers in a row`() = Wordy.answer(\"What is 1 plus 2 1?\").toUnit()\n\n    @Ignore\n    @Test(expected = Exception::class)\n    fun `reject postfix notation`() = Wordy.answer(\"What is 1 2 plus?\").toUnit()\n\n    @Ignore\n    @Test(expected = Exception::class)\n    fun `reject prefix notation`() = Wordy.answer(\"What is plus 1 2?\").toUnit()\n\n    // Additional tests for this track\n\n    @Ignore\n    @Test(expected = Exception::class)\n    fun `missing operation`() = Wordy.answer(\"What is 2 2 minus 3?\").toUnit()\n\n    @Ignore\n    @Test(expected = Exception::class)\n    fun `missing number`() = Wordy.answer(\"What is 7 plus multiplied by -2?\").toUnit()\n\n    // Bonus Question\n    @Ignore\n    @Test\n    fun power() = assertEquals(32, Wordy.answer(\"What is 2 raised to the 5th power?\"))\n\n    private fun Any.toUnit() = Unit // JUnit needs functions to return Unit\n}\n"
  },
  {
    "path": "exercises/practice/yacht/.docs/instructions.md",
    "content": "# Instructions\n\nGiven five dice and a category, calculate the score of the dice for that category.\n\n~~~~exercism/note\nYou'll always be presented with five dice.\nEach dice's value will be between one and six inclusively.\nThe dice may be unordered.\n~~~~\n\n## Scores in Yacht\n\n| Category        | Score                  | Description                              | Example             |\n| --------------- | ---------------------- | ---------------------------------------- | ------------------- |\n| Ones            | 1 × number of ones     | Any combination                          | 1 1 1 4 5 scores 3  |\n| Twos            | 2 × number of twos     | Any combination                          | 2 2 3 4 5 scores 4  |\n| Threes          | 3 × number of threes   | Any combination                          | 3 3 3 3 3 scores 15 |\n| Fours           | 4 × number of fours    | Any combination                          | 1 2 3 3 5 scores 0  |\n| Fives           | 5 × number of fives    | Any combination                          | 5 1 5 2 5 scores 15 |\n| Sixes           | 6 × number of sixes    | Any combination                          | 2 3 4 5 6 scores 6  |\n| Full House      | Total of the dice      | Three of one number and two of another   | 3 3 3 5 5 scores 19 |\n| Four of a Kind  | Total of the four dice | At least four dice showing the same face | 4 4 4 4 6 scores 16 |\n| Little Straight | 30 points              | 1-2-3-4-5                                | 1 2 3 4 5 scores 30 |\n| Big Straight    | 30 points              | 2-3-4-5-6                                | 2 3 4 5 6 scores 30 |\n| Choice          | Sum of the dice        | Any combination                          | 2 3 3 4 6 scores 18 |\n| Yacht           | 50 points              | All five dice showing the same face      | 4 4 4 4 4 scores 50 |\n\nIf the dice do **not** satisfy the requirements of a category, the score is zero.\nIf, for example, _Four Of A Kind_ is entered in the _Yacht_ category, zero points are scored.\nA _Yacht_ scores zero if entered in the _Full House_ category.\n"
  },
  {
    "path": "exercises/practice/yacht/.docs/introduction.md",
    "content": "# Introduction\n\nEach year, something new is \"all the rage\" in your high school.\nThis year it is a dice game: [Yacht][yacht].\n\nThe game of Yacht is from the same family as Poker Dice, Generala and particularly Yahtzee, of which it is a precursor.\nThe game consists of twelve rounds.\nIn each, five dice are rolled and the player chooses one of twelve categories.\nThe chosen category is then used to score the throw of the dice.\n\n[yacht]: https://en.wikipedia.org/wiki/Yacht_(dice_game)\n"
  },
  {
    "path": "exercises/practice/yacht/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/Yacht.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/YachtTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/Yacht.kt\"\n    ],\n    \"editor\": [\n      \"src/main/kotlin/YachtCategory.kt\"\n    ]\n  },\n  \"blurb\": \"Score a single throw of dice in the game Yacht.\",\n  \"source\": \"James Kilfiger, using Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Yacht_(dice_game)\"\n}\n"
  },
  {
    "path": "exercises/practice/yacht/.meta/src/reference/kotlin/Yacht.kt",
    "content": "import YachtCategory.*\n\nobject Yacht {\n\n    fun solve(category: YachtCategory, vararg dices: Int): Int = when (category) {\n        YACHT -> if (dices.distinct().size == 1) 50 else 0\n        ONES -> dices.filter { it == 1 }.sum()\n        TWOS -> dices.filter { it == 2 }.sum()\n        THREES -> dices.filter { it == 3 }.sum()\n        FOURS -> dices.filter { it == 4 }.sum()\n        FIVES -> dices.filter { it == 5 }.sum()\n        SIXES -> dices.filter { it == 6 }.sum()\n        FULL_HOUSE -> {\n            val counts = dices.groupBy { it }.map { it.key to it.value.count() }.sortedByDescending { it.second }\n            if (counts.size >= 2 && counts[0].second >= 3 && counts[1].second >= 2) {\n                counts[0].first * counts[0].second + counts[1].first * counts[1].second\n            } else 0\n        }\n        FOUR_OF_A_KIND -> dices.groupBy { it }.filter { it.value.size >= 4 }.keys.sumOf { it * 4 }\n        LITTLE_STRAIGHT -> if ((1..5).all { dices.contains(it) }) 30 else 0\n        BIG_STRAIGHT -> if ((2..6).all { dices.contains(it) }) 30 else 0\n        CHOICE -> dices.sum()\n    }\n}\n"
  },
  {
    "path": "exercises/practice/yacht/.meta/src/reference/kotlin/YachtCategory.kt",
    "content": "enum class YachtCategory {\n    YACHT,\n    ONES,\n    TWOS,\n    THREES,\n    FOURS,\n    FIVES,\n    SIXES,\n    FULL_HOUSE,\n    FOUR_OF_A_KIND,\n    LITTLE_STRAIGHT,\n    BIG_STRAIGHT,\n    CHOICE\n}\n"
  },
  {
    "path": "exercises/practice/yacht/.meta/tests.toml",
    "content": "[canonical-tests]\n\n# Yacht\n\"3060e4a5-4063-4deb-a380-a630b43a84b6\" = true\n\n# Not Yacht\n\"15026df2-f567-482f-b4d5-5297d57769d9\" = true\n\n# Ones\n\"36b6af0c-ca06-4666-97de-5d31213957a4\" = true\n\n# Ones, out of order\n\"023a07c8-6c6e-44d0-bc17-efc5e1b8205a\" = true\n\n# No ones\n\"7189afac-cccd-4a74-8182-1cb1f374e496\" = true\n\n# Twos\n\"793c4292-dd14-49c4-9707-6d9c56cee725\" = true\n\n# Fours\n\"dc41bceb-d0c5-4634-a734-c01b4233a0c6\" = true\n\n# Yacht counted as threes\n\"f6125417-5c8a-4bca-bc5b-b4b76d0d28c8\" = true\n\n# Yacht of 3s counted as fives\n\"464fc809-96ed-46e4-acb8-d44e302e9726\" = true\n\n# Sixes\n\"e8a036e0-9d21-443a-8b5f-e15a9e19a761\" = true\n\n# Full house two small, three big\n\"51cb26db-6b24-49af-a9ff-12f53b252eea\" = true\n\n# Full house three small, two big\n\"1822ca9d-f235-4447-b430-2e8cfc448f0c\" = true\n\n# Two pair is not a full house\n\"b208a3fc-db2e-4363-a936-9e9a71e69c07\" = true\n\n# Four of a kind is not a full house\n\"b90209c3-5956-445b-8a0b-0ac8b906b1c2\" = true\n\n# Yacht is not a full house\n\"32a3f4ee-9142-4edf-ba70-6c0f96eb4b0c\" = true\n\n# Four of a Kind\n\"b286084d-0568-4460-844a-ba79d71d79c6\" = true\n\n# Yacht can be scored as Four of a Kind\n\"f25c0c90-5397-4732-9779-b1e9b5f612ca\" = true\n\n# Full house is not Four of a Kind\n\"9f8ef4f0-72bb-401a-a871-cbad39c9cb08\" = true\n\n# Little Straight\n\"b4743c82-1eb8-4a65-98f7-33ad126905cd\" = true\n\n# Little Straight as Big Straight\n\"7ac08422-41bf-459c-8187-a38a12d080bc\" = true\n\n# Four in order but not a little straight\n\"97bde8f7-9058-43ea-9de7-0bc3ed6d3002\" = true\n\n# No pairs but not a little straight\n\"cef35ff9-9c5e-4fd2-ae95-6e4af5e95a99\" = true\n\n# Minimum is 1, maximum is 5, but not a little straight\n\"fd785ad2-c060-4e45-81c6-ea2bbb781b9d\" = true\n\n# Big Straight\n\"35bd74a6-5cf6-431a-97a3-4f713663f467\" = true\n\n# Big Straight as little straight\n\"87c67e1e-3e87-4f3a-a9b1-62927822b250\" = true\n\n# No pairs but not a big straight\n\"c1fa0a3a-40ba-4153-a42d-32bc34d2521e\" = true\n\n# Choice\n\"207e7300-5d10-43e5-afdd-213e3ac8827d\" = true\n\n# Yacht as choice\n\"b524c0cf-32d2-4b40-8fb3-be3500f3f135\" = true\n"
  },
  {
    "path": "exercises/practice/yacht/.meta/version",
    "content": "1.2.0\n"
  },
  {
    "path": "exercises/practice/yacht/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/yacht/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/yacht/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/yacht/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/yacht/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/yacht/src/main/kotlin/Yacht.kt",
    "content": "object Yacht {\n\n    fun solve(category: YachtCategory, vararg dices: Int): Int {\n        TODO(\"Implement this to complete the task\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/yacht/src/main/kotlin/YachtCategory.kt",
    "content": "enum class YachtCategory {\n    YACHT,\n    ONES,\n    TWOS,\n    THREES,\n    FOURS,\n    FIVES,\n    SIXES,\n    FULL_HOUSE,\n    FOUR_OF_A_KIND,\n    LITTLE_STRAIGHT,\n    BIG_STRAIGHT,\n    CHOICE\n}\n"
  },
  {
    "path": "exercises/practice/yacht/src/test/kotlin/YachtTest.kt",
    "content": "import kotlin.test.Ignore\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\nimport YachtCategory.*\n\nclass YachtTest {\n\n    @Test\n    fun yacht() = assertEquals(50, Yacht.solve(YACHT, 5, 5, 5, 5, 5))\n\n    @Ignore\n    @Test\n    fun `not yacht`() = assertEquals(0, Yacht.solve(YACHT, 1, 3, 3, 2, 5))\n\n    @Ignore\n    @Test\n    fun ones() = assertEquals(3, Yacht.solve(ONES, 1, 1, 1, 3, 5))\n\n    @Ignore\n    @Test\n    fun `ones out of order`() = assertEquals(3, Yacht.solve(ONES, 3, 1, 1, 5, 1))\n\n    @Ignore\n    @Test\n    fun `no ones`() = assertEquals(0, Yacht.solve(ONES, 4, 3, 6, 5, 5))\n\n    @Ignore\n    @Test\n    fun twos() = assertEquals(2, Yacht.solve(TWOS, 2, 3, 4, 5, 6))\n\n    @Ignore\n    @Test\n    fun fours() = assertEquals(8, Yacht.solve(FOURS, 1, 4, 1, 4, 1))\n\n    @Ignore\n    @Test\n    fun `yacht counted as threes`() = assertEquals(15, Yacht.solve(THREES, 3, 3, 3, 3, 3))\n\n    @Ignore\n    @Test\n    fun `yacht of threes counted as fives`() = assertEquals(0, Yacht.solve(FIVES, 3, 3, 3, 3, 3))\n\n    @Ignore\n    @Test\n    fun sixes() = assertEquals(6, Yacht.solve(SIXES, 2, 3, 4, 5, 6))\n\n    @Ignore\n    @Test\n    fun `full house two small three big`() = assertEquals(16, Yacht.solve(FULL_HOUSE, 2, 2, 4, 4, 4))\n\n    @Ignore\n    @Test\n    fun `full house three small two big`() = assertEquals(19, Yacht.solve(FULL_HOUSE, 5, 3, 3, 5, 3))\n\n    @Ignore\n    @Test\n    fun `two pair is not a full house`() = assertEquals(0, Yacht.solve(FULL_HOUSE, 2, 2, 4, 4, 5))\n\n    @Ignore\n    @Test\n    fun `four of a kind is not a full house`() = assertEquals(0, Yacht.solve(FULL_HOUSE, 1, 4, 4, 4, 4))\n\n    @Ignore\n    @Test\n    fun `yacht is not a full house`() = assertEquals(0, Yacht.solve(FULL_HOUSE, 2, 2, 2, 2, 2))\n\n    @Ignore\n    @Test\n    fun `four of a kind`() = assertEquals(24, Yacht.solve(FOUR_OF_A_KIND, 6, 6, 4, 6, 6))\n\n    @Ignore\n    @Test\n    fun `yacht can be scored as four of a kind`() = assertEquals(12, Yacht.solve(FOUR_OF_A_KIND, 3, 3, 3, 3, 3))\n\n    @Ignore\n    @Test\n    fun `full house is not four of a kind`() = assertEquals(0, Yacht.solve(FOUR_OF_A_KIND, 3, 3, 3, 5, 5))\n\n    @Ignore\n    @Test\n    fun `little straight`() = assertEquals(30, Yacht.solve(LITTLE_STRAIGHT, 3, 5, 4, 1, 2))\n\n    @Ignore\n    @Test\n    fun `little straight as big straight`() = assertEquals(0, Yacht.solve(BIG_STRAIGHT, 1, 2, 3, 4, 5))\n\n    @Ignore\n    @Test\n    fun `four in order but not a little straight`() = assertEquals(0, Yacht.solve(LITTLE_STRAIGHT, 1, 1, 2, 3, 4))\n\n    @Ignore\n    @Test\n    fun `no pairs but not a little straight`() = assertEquals(0, Yacht.solve(LITTLE_STRAIGHT, 1, 2, 3, 4, 6))\n\n    @Ignore\n    @Test\n    fun `minimum is 1 maximum is 5 but not a little straight`() =\n        assertEquals(0, Yacht.solve(LITTLE_STRAIGHT, 1, 1, 3, 4, 5))\n\n    @Ignore\n    @Test\n    fun `big straight`() = assertEquals(30, Yacht.solve(BIG_STRAIGHT, 4, 6, 2, 5, 3))\n\n    @Ignore\n    @Test\n    fun `big straight as little straight`() = assertEquals(0, Yacht.solve(LITTLE_STRAIGHT, 6, 5, 4, 3, 2))\n\n    @Ignore\n    @Test\n    fun `no pairs but not a big straight`() = assertEquals(0, Yacht.solve(BIG_STRAIGHT, 6, 5, 4, 3, 1))\n\n    @Ignore\n    @Test\n    fun choice() = assertEquals(23, Yacht.solve(CHOICE, 3, 3, 5, 6, 6))\n\n    @Ignore\n    @Test\n    fun `yacht as choice`() = assertEquals(10, Yacht.solve(CHOICE, 2, 2, 2, 2, 2))\n}\n"
  },
  {
    "path": "exercises/practice/zebra-puzzle/.docs/instructions.md",
    "content": "# Instructions\n\nYour task is to solve the Zebra Puzzle to find the answer to these two questions:\n\n- Which of the residents drinks water?\n- Who owns the zebra?\n\n## Puzzle\n\nThe following 15 statements are all known to be true:\n\n1. There are five houses.\n2. The Englishman lives in the red house.\n3. The Spaniard owns the dog.\n4. The person in the green house drinks coffee.\n5. The Ukrainian drinks tea.\n6. The green house is immediately to the right of the ivory house.\n7. The snail owner likes to go dancing.\n8. The person in the yellow house is a painter.\n9. The person in the middle house drinks milk.\n10. The Norwegian lives in the first house.\n11. The person who enjoys reading lives in the house next to the person with the fox.\n12. The painter's house is next to the house with the horse.\n13. The person who plays football drinks orange juice.\n14. The Japanese person plays chess.\n15. The Norwegian lives next to the blue house.\n\nAdditionally, 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.\n\n~~~~exercism/note\nThere are 24 billion (5!⁵ = 24,883,200,000) possible solutions, so try ruling out as many solutions as possible.\n~~~~\n"
  },
  {
    "path": "exercises/practice/zebra-puzzle/.docs/introduction.md",
    "content": "# Introduction\n\nThe Zebra Puzzle is a famous logic puzzle in which there are five houses, each painted a different color.\nThe houses have different inhabitants, who have different nationalities, own different pets, drink different beverages and enjoy different hobbies.\n\nTo help you solve the puzzle, you're given 15 statements describing the solution.\nHowever, only by combining the information in _all_ statements will you be able to find the solution to the puzzle.\n\n~~~~exercism/note\nThe Zebra Puzzle is a [Constraint satisfaction problem (CSP)][constraint-satisfaction-problem].\nIn such a problem, you have a set of possible values and a set of constraints that limit which values are valid.\nAnother well-known CSP is Sudoku.\n\n[constraint-satisfaction-problem]: https://en.wikipedia.org/wiki/Constraint_satisfaction_problem\n~~~~\n"
  },
  {
    "path": "exercises/practice/zebra-puzzle/.meta/config.json",
    "content": "{\n  \"authors\": [\n    \"lathspell\"\n  ],\n  \"contributors\": [\n    \"eparovyshnaya\",\n    \"uzilan\"\n  ],\n  \"files\": {\n    \"solution\": [\n      \"src/main/kotlin/ZebraPuzzle.kt\"\n    ],\n    \"test\": [\n      \"src/test/kotlin/ZebraPuzzleTest.kt\"\n    ],\n    \"example\": [\n      \".meta/src/reference/kotlin/ZebraPuzzle.kt\"\n    ]\n  },\n  \"blurb\": \"Solve the zebra puzzle.\",\n  \"source\": \"Wikipedia\",\n  \"source_url\": \"https://en.wikipedia.org/wiki/Zebra_Puzzle\"\n}\n"
  },
  {
    "path": "exercises/practice/zebra-puzzle/.meta/src/reference/kotlin/HeapsPermutation.kt",
    "content": "/** Heap's Algorithm as seen on https://en.wikipedia.org/wiki/Heap%27s_algorithm. */\nobject HeapsPermutation {\n\n    fun permute(vararg input: Int): Set<IntArray> = permute(input.size, input)\n\n    private fun permute(k: Int, input: IntArray): Set<IntArray> =\n            (0 until k).flatMap { i ->\n                if (k == 1) {\n                    // Return a new object, as the received one is a mutable object which will be modified in swap()\n                    setOf(input.copyOf())\n                } else {\n                    val roundResults = permute(k - 1, input)\n                    if (isEven(k)) {\n                        swap(input, i, k - 1)\n                    } else {\n                        swap(input, 0, k - 1)\n                    }\n                    roundResults\n                }\n            }.toSet()\n\n    private fun isEven(i: Int) = ((i % 2) == 0)\n\n    private fun swap(input: IntArray, a: Int, b: Int) {\n        val tmp = input[a]\n        input[a] = input[b]\n        input[b] = tmp\n    }\n}\n"
  },
  {
    "path": "exercises/practice/zebra-puzzle/.meta/src/reference/kotlin/ZebraPuzzle.kt",
    "content": "class ZebraPuzzle {\n\n    private var red = 0\n    private var green = 0\n    private var ivory = 0\n    private var yellow = 0\n    private var blue = 0\n\n    private var english = 0\n    private var spaniard = 0\n    private var ukrainian = 0\n    private var japanese = 0\n    private var norwegian = 0\n\n    private var coffee = 0\n    private var tea = 0\n    private var milk = 0\n    private var orangejuice = 0\n    private var water = 0\n\n    private var oldgold = 0\n    private var kools = 0\n    private var chesterfields = 0\n    private var luckystrike = 0\n    private var parliaments = 0\n\n    private var dog = 0\n    private var snails = 0\n    private var fox = 0\n    private var horse = 0\n    private var zebra = 0\n\n    private lateinit var nationalityNames: Map<Int, String>\n    private lateinit var waterDrinker: String\n    private lateinit var zebraOwner: String\n\n    companion object {\n        private const val FIRST = 1\n        private const val MIDDLE = 3\n\n        private fun isJustRightOf(neighbourA: Int, neighbourB: Int): Boolean {\n            return neighbourA - 1 == neighbourB\n        }\n\n        private fun nextTo(neighbourA: Int, neighbourB: Int): Boolean {\n            return isJustRightOf(neighbourA, neighbourB) || isJustRightOf(neighbourB, neighbourA)\n        }\n\n        private fun allHouseAssignmentPermutations() = HeapsPermutation.permute(1, 2, 3, 4, 5)\n    }\n\n    init {\n        solve()\n    }\n\n    fun drinksWater() = waterDrinker\n\n    fun ownsZebra() = zebraOwner\n\n    private fun solve() {\n        allHouseAssignmentPermutations().forEach { solveHouseColors(it) }\n    }\n\n    private fun solveHouseColors(permutation: IntArray) {\n        red = permutation[0]\n        green = permutation[1]\n        ivory = permutation[2]\n        yellow = permutation[3]\n        blue = permutation[4]\n\n        if (isJustRightOf(green, ivory)) {\n            allHouseAssignmentPermutations().forEach { solveNationalities(it) }\n        }\n    }\n\n    private fun solveNationalities(permutation: IntArray) {\n        english = permutation[0]\n        spaniard = permutation[1]\n        ukrainian = permutation[2]\n        japanese = permutation[3]\n        norwegian = permutation[4]\n\n        if (red == english && norwegian == FIRST && nextTo(norwegian, blue)) {\n            // record names for later use\n            nationalityNames = mapOf(\n                    english to \"Englishman\",\n                    spaniard to \"Spaniard\",\n                    ukrainian to \"Ukrainian\",\n                    japanese to \"Japanese\",\n                    norwegian to \"Norwegian\")\n            allHouseAssignmentPermutations().forEach { solveBeverages(it) }\n        }\n    }\n\n    private fun solveBeverages(permutation: IntArray) {\n        coffee = permutation[0]\n        tea = permutation[1]\n        milk = permutation[2]\n        orangejuice = permutation[3]\n        water = permutation[4]\n\n        if (coffee == green && ukrainian == tea && milk == MIDDLE) {\n            allHouseAssignmentPermutations().forEach { solveCigars(it) }\n        }\n    }\n\n    private fun solveCigars(permutation: IntArray) {\n        oldgold = permutation[0]\n        kools = permutation[1]\n        chesterfields = permutation[2]\n        luckystrike = permutation[3]\n        parliaments = permutation[4]\n\n        if (kools == yellow && luckystrike == orangejuice && japanese == parliaments) {\n            allHouseAssignmentPermutations().forEach { solvePets(it) }\n        }\n    }\n\n    private fun solvePets(permutation: IntArray) {\n        dog = permutation[0]\n        snails = permutation[1]\n        fox = permutation[2]\n        horse = permutation[3]\n        zebra = permutation[4]\n\n        if (spaniard == dog && oldgold == snails && nextTo(chesterfields, fox) && nextTo(kools, horse)) {\n            waterDrinker = nationalityNames[water] ?: error(\"Water drinker not found!\")\n            zebraOwner = nationalityNames[zebra] ?: error(\"Zebra owner not found!\")\n        }\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/zebra-puzzle/.meta/tests.toml",
    "content": "# This is an auto-generated file.\n#\n# Regenerating this file via `configlet sync` will:\n# - Recreate every `description` key/value pair\n# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications\n# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)\n# - Preserve any other key/value pair\n#\n# As user-added comments (using the # character) will be removed when this file\n# is regenerated, comments can be added via a `comment` key.\n\n[16efb4e4-8ad7-4d5e-ba96-e5537b66fd42]\ndescription = \"resident who drinks water\"\n\n[084d5b8b-24e2-40e6-b008-c800da8cd257]\ndescription = \"resident who owns zebra\"\n"
  },
  {
    "path": "exercises/practice/zebra-puzzle/.meta/version",
    "content": "1.1.0\n"
  },
  {
    "path": "exercises/practice/zebra-puzzle/build.gradle.kts",
    "content": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n    kotlin(\"jvm\")\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(kotlin(\"stdlib-jdk8\"))\n    \n    testImplementation(\"junit:junit:4.13.2\")\n    testImplementation(kotlin(\"test-junit\"))\n}\n\ntasks.withType<Test> {\n    testLogging {\n        exceptionFormat = TestExceptionFormat.FULL\n        events(\"passed\", \"failed\", \"skipped\")\n    }\n}\n"
  },
  {
    "path": "exercises/practice/zebra-puzzle/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "exercises/practice/zebra-puzzle/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "exercises/practice/zebra-puzzle/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "exercises/practice/zebra-puzzle/settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/practice/zebra-puzzle/src/main/kotlin/ZebraPuzzle.kt",
    "content": "class ZebraPuzzle() {\n\n    fun drinksWater(): String {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n    fun ownsZebra(): String {\n        TODO(\"Implement this function to complete the task\")\n    }\n\n}\n"
  },
  {
    "path": "exercises/practice/zebra-puzzle/src/test/kotlin/ZebraPuzzleTest.kt",
    "content": "import kotlin.test.Ignore\nimport kotlin.test.Test\nimport kotlin.test.assertEquals\n\nclass ZebraPuzzleTest {\n\n    @Test\n    fun `resident who drinks water`() = assertEquals(\"Norwegian\", ZebraPuzzle().drinksWater())\n\n    @Ignore\n    @Test\n    fun `resident who owns zebra`() = assertEquals(\"Japanese\", ZebraPuzzle().ownsZebra())\n\n}\n"
  },
  {
    "path": "exercises/settings.gradle.kts",
    "content": "include(\n    \"concept:annalyns-infiltration\",\n    \"concept:cars-assemble\",\n    \"concept:log-levels\",\n    \"concept:lucians-luscious-lasagna\",\n    \"practice:accumulate\",\n    \"practice:acronym\",\n    \"practice:all-your-base\",\n    \"practice:affine-cipher\",\n    \"practice:allergies\",\n    \"practice:anagram\",\n    \"practice:armstrong-numbers\",\n    \"practice:atbash-cipher\",\n    \"practice:bank-account\",\n    \"practice:beer-song\",\n    \"practice:binary\",\n    \"practice:binary-search\",\n    \"practice:binary-search-tree\",\n    \"practice:bob\",\n    \"practice:bottle-song\",\n    \"practice:bowling\",\n    \"practice:change\",\n    \"practice:circular-buffer\",\n    \"practice:clock\",\n    \"practice:collatz-conjecture\",\n    \"practice:complex-numbers\",\n    \"practice:crypto-square\",\n    \"practice:custom-set\",\n    \"practice:darts\",\n    \"practice:diamond\",\n    \"practice:difference-of-squares\",\n    \"practice:diffie-hellman\",\n    \"practice:dnd-character\",\n    \"practice:dominoes\",\n    \"practice:eliuds-eggs\",\n    \"practice:etl\",\n    \"practice:flatten-array\",\n    \"practice:flower-field\",\n    \"practice:forth\",\n    \"practice:gigasecond\",\n    \"practice:grade-school\",\n    \"practice:grains\",\n    \"practice:hamming\",\n    \"practice:hello-world\",\n    \"practice:hexadecimal\",\n    \"practice:isbn-verifier\",\n    \"practice:isogram\",\n    \"practice:kindergarten-garden\",\n    \"practice:knapsack\",\n    \"practice:largest-series-product\",\n    \"practice:leap\",\n    \"practice:linked-list\",\n    \"practice:list-ops\",\n    \"practice:luhn\",\n    \"practice:matching-brackets\",\n    \"practice:matrix\",\n    \"practice:meetup\",\n    \"practice:minesweeper\",\n    \"practice:nth-prime\",\n    \"practice:nucleotide-count\",\n    \"practice:pangram\",\n    \"practice:pascals-triangle\",\n    \"practice:perfect-numbers\",\n    \"practice:phone-number\",\n    \"practice:pig-latin\",\n    \"practice:prime-factors\",\n    \"practice:protein-translation\",\n    \"practice:rail-fence-cipher\",\n    \"practice:raindrops\",\n    \"practice:react\",\n    \"practice:resistor-color\",\n    \"practice:resistor-color-duo\",\n    \"practice:resistor-color-trio\",\n    \"practice:reverse-string\",\n    \"practice:rna-transcription\",\n    \"practice:robot-name\",\n    \"practice:robot-simulator\",\n    \"practice:roman-numerals\",\n    \"practice:rotational-cipher\",\n    \"practice:run-length-encoding\",\n    \"practice:saddle-points\",\n    \"practice:say\",\n    \"practice:scale-generator\",\n    \"practice:scrabble-score\",\n    \"practice:secret-handshake\",\n    \"practice:series\",\n    \"practice:sieve\",\n    \"practice:simple-cipher\",\n    \"practice:space-age\",\n    \"practice:spiral-matrix\",\n    \"practice:strain\",\n    \"practice:sublist\",\n    \"practice:sum-of-multiples\",\n    \"practice:transpose\",\n    \"practice:triangle\",\n    \"practice:two-fer\",\n    \"practice:word-count\",\n    \"practice:wordy\",\n    \"practice:yacht\",\n    \"practice:zebra-puzzle\",\n)\n\npluginManagement {\n    repositories {\n        mavenCentral()\n        gradlePluginPortal()\n    }\n    resolutionStrategy {\n        eachPlugin {\n            when (requested.id.id) {\n                \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "exercises/shared/.docs/help.md",
    "content": "# Help\n\nTo get help if you're having trouble, you can use one of the following resources:\n\n- [Kotlin Documentation](https://kotlinlang.org/docs/reference/)\n- [Kotlin Forums](https://discuss.kotlinlang.org/)\n- [Kotlin Slack Channel](http://kotlinlang.slack.com/): [get invite here](http://slack.kotlinlang.org/)\n- [Stack Overflow](https://stackoverflow.com/questions/tagged/kotlin)\n- [Reddit Channel](https://www.reddit.com/r/kotlin)\n- [Twitter](https://twitter.com/kotlin)\n"
  },
  {
    "path": "exercises/shared/.docs/tests.md",
    "content": "# Tests\n\nExecute the tests with:\n\n```bash\n$ gradlew test\n```\n\n> Use `gradlew.bat` if you're on Windows\n\n## Skipped tests\n\nIn the test suites all tests but the first have been skipped.\n\nOnce you get a test passing, you can enable the next one by removing the\n`@Ignore` annotation.\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.4-bin.zip\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\nAPP_HOME=$( cd \"${APP_HOME:-./}\" && pwd -P ) || exit\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=${0##*/}\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n# Collect all arguments for the java command;\n#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of\n#     shell script including quotes and variable substitutions, so put them in\n#     double quotes to make sure that they get re-expanded; and\n#   * put everything else in single quotes, so that it's not re-expanded.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\r\n@rem you may not use this file except in compliance with the License.\r\n@rem You may obtain a copy of the License at\r\n@rem\r\n@rem      https://www.apache.org/licenses/LICENSE-2.0\r\n@rem\r\n@rem Unless required by applicable law or agreed to in writing, software\r\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\r\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n@rem See the License for the specific language governing permissions and\r\n@rem limitations under the License.\r\n@rem\r\n\r\n@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\r\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto execute\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto execute\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "reference/implementing-a-concept-exercise.md",
    "content": "# How to implement a Kotlin concept exercise\n\n```diff\n! WARNING! This document should be treated as a draft and will be actively changing. Sections that marked as WIP requires attention/rework from contributors.\n```\n\nThis document describes the steps required to implement a concept exercise in any v3 track.\n\n**Please please please read the docs before starting.** Posting PRs without reading these docs will be a lot more frustrating for you during the review cycle, and exhaust Exercism's maintainers' time. So, before diving into the implementation, please read the following documents:\n\n- [The features of v3][docs-features-of-v3].\n- [Rationale for v3][docs-rationale-for-v3].\n- [What are concept exercise and how they are structured?][docs-concept-exercises]\n\nPlease also watch the following video:\n\n- [The Anatomy of a Concept Exercise][anatomy-of-a-concept-exercise].\n\nAs this document is generic, the following placeholders are used:\n\n- `<exercise-slug>`: the name of the exercise in kebab-case (e.g. `calculator-conundrum`).\n- `<ExerciseSlug>`: the name of the exercise in PascalCase (e.g. `CalculatorConundrum`).\n- `<concept-slug>`: the slug of one of the exercise's concepts in kebab-case (e.g. `anonymous-methods`).\n\nBefore implementing the exercise, please make sure you have a good understanding of what the exercise should be teaching (and what not). This information can be found in the [exercise's GitHub issue](https://github.com/exercism/v3/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Atrack%2Fkotlin+Implement+new+concept+exercise+in%3Atitle).\n\nAny concept exercise in any v3 track requires the following files to be created:\n\n<pre>\nlanguages\n└── kotlin\n    ├── concepts\n    |   └── &lt;concept-slug&gt;\n    |       ├── about.md\n    |       └── links.json\n    └── exercises\n        └── concept\n            └── &lt;exercise-slug>\n                ├── .docs\n                |   ├── instructions.md\n                |   ├── introduction.md\n                |   ├── hints.md\n                |   └── source.md (required if there are third-party sources)\n                ├── .meta\n                |   |── design.md\n                |   |── config.json\n                |   └── Exemplar.kt\n                ├── src\n                |   ├── main\n                |   | \t└── kotlin\n                |   | \t\t└── &lt;ExerciseSlug>.kt\n                |   └── test\n                |    \t└── kotlin\n                |    \t\t└── &lt;ExerciseSlug>Test.kt\n                └── gradle\n                |\t└── wrapper\n                | \t\t├── gradle-wrapper.jar\n                |\t\t└── gradle-wrapper.properties\n                ├── build.gradle.kts\n                ├── gradlew\n                └── gradlew.bat\n</pre>\n\n## Step 1: Add code files\n\nThe code files are track-specific and should be designed to help the student learn the exercise's concepts. The following Kotlin code files must be added (not necessarily in this order):\n\n- A stub implementation file (`src/main/kotlin/<ExerciseSlug>.kt`).\n- A file containing the test suite (`src/test/kotlin/<ExerciseSlug>.kt`).\n- An exemplar implementation file that passes all the tests (`meta/Example.kt`).\n\nWhat these files look like depends on your track. Note that some tracks might require more files in addition to the three files just mentioned.\n\n## Step 2: Add documentation files\n\nHow to create the files common to all tracks is described in the [how to implement a concept exercise document][how-to-implement-a-concept-exercise].\n\n## Step 3: Add analyzer (optional)\n\n```diff\n! WIP ignore this for now as we don't have proper analyzer yet\n```\n\nSome exercises could benefit from having an exercise-specific analyzer. If so, please check the track's analyzer document for details on how to do this.\n\n_Skip this step if you're not sure what to do._\n\n## Step 4: Add representation (optional)\n\n```diff\n! WIP ignore this for now as we don't have proper analyzer yet\n```\n\nSome exercises could benefit from having an custom representation as generated by the track's representer. If so, please check the track's representer document for details on how to do this.\n\n_Skip this step if you're not sure what to do._\n\n## Inspiration\n\nWhen implementing an exercise, it can be very useful to look at the exercises the track has already implemented. You can also check the exercise's [general concepts documents][reference] to see if other languages that have already an exercise for that concept.\n\n## Help\n\nIf you have any questions regarding implementing this exercise, please post them as comments in the exercise's GitHub issue.\n\n[reference]: ../reference/README.md\n[docs-concept-exercises]: https://github.com/exercism/v3/blob/main/docs/concept-exercises.md\n[docs-rationale-for-v3]: https://github.com/exercism/v3/blob/main/docs/rationale-for-v3.md\n[docs-features-of-v3]: https://github.com/exercism/v3/blob/main/docs/features-of-v3.md\n[anatomy-of-a-concept-exercise]: https://www.youtube.com/watch?v=gkbBqd7hPrA\n[how-to-implement-a-concept-exercise]: https://github.com/exercism/v3/blob/main/docs/maintainers/generic-how-to-implement-a-concept-exercise.md\n"
  },
  {
    "path": "scripts/canonical_data_check.sh",
    "content": "#!/usr/bin/env bash\n\nprint_usage() {\n    echo \"Usage: ./canonical_data_check.sh -t path/to/track -s path/to/problem/specifications\"\n}\n\n# Execution begins\n\ncommand -v jq >/dev/null 2>&1 || {\n    echo >&2 \"This script requires jq but it's not installed. Aborting.\"\n    exit 1\n}\n\nnum_args=$#\n\nif [ $num_args -eq 0 ]\nthen\n    print_usage\n    exit 0\nfi\n\npath_to_track=\npath_to_problem_specifications=\n\nwhile getopts \":t:s:\" option\ndo\n    case \"$option\" in\n        \"t\")\n            path_to_track=\"$OPTARG\"\n            ;;\n        \"s\")\n            path_to_problem_specifications=\"$OPTARG\"\n            ;;\n        *)\n            echo \"Unrecognized option. Aborting.\"\n            print_usage\n            exit 1\n            ;;\n    esac\ndone\n\nif [ -z \"$path_to_track\" ]\nthen\n    echo \"Path to track missing.\"\n    print_usage\n    exit 1\nfi\n\nif [ -z \"$path_to_problem_specifications\" ]\nthen\n    echo \"Path to problem specifications missing.\"\n    print_usage\n    exit 1\nfi\n\nconfig_file_path=\"$path_to_track/config.json\"\n\nif ! [ -f \"$config_file_path\" ]\nthen\n    echo \"Config file not found at $config_file_path.\"\n    exit 1\nfi\n\ntrack_exercise_slugs=$(jq '.exercises[] | select(has(\"deprecated\") | not) | .slug' $config_file_path | tr -d \"\\\"\")\nupdate_needed_count=0\n\nfor slug in $track_exercise_slugs\ndo\n    canonical_data_folder_path=\"$path_to_problem_specifications/exercises/$slug\"\n\n    if ! [ -d \"$canonical_data_folder_path\" ]\n    then\n        echo \"Canonical data folder $canonical_data_folder_path not found. Aborting.\"\n        exit 1\n    fi\n\n    canonical_data_file_path=\"$canonical_data_folder_path/canonical-data.json\"\n\n    if ! [ -f \"$canonical_data_file_path\" ]\n    then\n        # echo \"$slug: no canonical data found.\"\n        continue\n    fi\n\n    canonical_data_version=$(jq '.version' $canonical_data_file_path | tr -d \"\\\"\")\n\n    track_exercise_version_file_path=\"$path_to_track/exercises/$slug/.meta/version\"\n\n    if ! [ -f \"$track_exercise_version_file_path\" ]\n    then\n        echo \"$slug: needs update or version file (v$canonical_data_version).\"\n        update_needed_count=$((update_needed_count + 1))\n        continue\n    fi\n\n    track_data_version=$(cat $track_exercise_version_file_path)\n\n    if [ \"$track_data_version\" = \"$canonical_data_version\" ]\n    then\n        # echo \"$slug: up-to-date.\"\n        continue\n    else\n        update_needed_count=$((update_needed_count + 1))\n        echo \"$slug: needs update (v$track_data_version -> v$canonical_data_version).\"\n    fi\n\ndone\n\nif [ $update_needed_count -eq 0 ]\nthen\n    echo \"All exercises are up to date!\"\nfi\n"
  },
  {
    "path": "scripts/fix_exercises_symlinks.sh",
    "content": "#!/usr/bin/env bash\n\n# This script looks through each exercise folder to identify symlinked files in the .meta folder and replaces the files\n# with actual symlinks. This is mainly to fix weird behavior with Git and symlinks.\n\ngrep -R -e '^\\.\\./\\.\\.' exercises | cut -d: -f1 - | while IFS= read -r file\ndo\n    dir=$(dirname \"$file\")\n    filename=$(basename \"$file\")\n    target=$(cat \"$file\")\n\n    echo \"Replacing ${file} with symlink to ${target}.\"\n\n    pushd \"$dir\" || continue\n    rm -f \"$filename\"\n    ln -s \"$target\" \"$filename\"\n    popd || continue\n\n    unset dir filename\ndone\n"
  },
  {
    "path": "scripts/updateGradleFilesFromTemplate.kts",
    "content": "#!/usr/bin/env kscript\n\nimport java.io.File\n\nfun updateGradleFiles() {\n    val exerciseDirs = File(\"exercises\").listFiles()\n        .filter { it.isDirectory }\n        .flatMap { it.listFiles().filter { it.resolve(\"src/main/kotlin\").exists() } }\n\n    val filesToCopy = listOf(\n        \"build.gradle.kts\",\n        \"settings.gradle.kts\",\n        \"gradle/\",\n        \"gradlew\",\n        \"gradlew.bat\"\n    )\n\n    val executables = listOf(\n        \"gradlew\",\n        \"gradlew.bat\"\n    )\n\n    exerciseDirs.forEach { dir ->\n        println(dir.name)\n\n        dir.resolve(\"build.gradle\")\n            .takeIf { it.exists() }\n            ?.delete()\n\n        val templateDir = File(\"_template\")\n\n        filesToCopy.forEach { file ->\n            val src = templateDir.resolve(file)\n            val dest = dir.resolve(file)\n\n            src.copyRecursively(dest, overwrite = true)\n\n            if (file in executables) {\n                dest.setExecutable(true)\n            }\n        }\n    }\n}\n\nupdateGradleFiles()\n"
  },
  {
    "path": "scripts/updateTemplateBuildFile.kts",
    "content": "#!/usr/bin/env kscript\n\nimport java.io.File\n\nfun updateTemplate() {\n    val versions = object {\n        val kotlin = \"1.6.0\"\n        val junit4 = \"4.13.2\"\n    }\n\n    File(\"_template\").resolve(\"build.gradle.kts\").writeText(\n        \"\"\"\n        import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n        \n        plugins {\n            kotlin(\"jvm\")\n        }\n        \n        repositories {\n            mavenCentral()\n        }\n        \n        dependencies {\n            implementation(kotlin(\"stdlib-jdk8\"))\n            \n            testImplementation(\"junit:junit:${versions.junit4}\")\n            testImplementation(kotlin(\"test-junit\"))\n        }\n        \n        tasks.withType<Test> {\n            testLogging {\n                exceptionFormat = TestExceptionFormat.FULL\n                events(\"passed\", \"failed\", \"skipped\")\n            }\n        }\n\n        \"\"\".trimIndent()\n    )\n\n    File(\"_template\").resolve(\"settings.gradle.kts\").writeText(\n        \"\"\"\n        pluginManagement {\n            repositories {\n                mavenCentral()\n                gradlePluginPortal()\n            }\n            resolutionStrategy {\n                eachPlugin {\n                    when (requested.id.id) {\n                        \"org.jetbrains.kotlin.jvm\" -> useModule(\"org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}\")\n                    }\n                }\n            }\n        }\n\n        \"\"\".trimIndent()\n    )\n}\n\nupdateTemplate()\n"
  }
]