From 3e163b1891a7cd73f861c0ab8d9d21befae100ca Mon Sep 17 00:00:00 2001 From: Exercism Bot Date: Fri, 11 Aug 2023 09:29:09 +0100 Subject: [PATCH 01/33] =?UTF-8?q?=F0=9F=A4=96=20Sync=20org-wide=20files=20?= =?UTF-8?q?to=20upstream=20repo=20(#9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More info: https://github.com/exercism/org-wide-files/commit/45f63ba1c13290b69e64fcf9fa6103698f97ce71 --- LICENSE | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index ef5d211..90e73be 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Exercism +Copyright (c) 2021 Exercism Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. From ff9aac31696e9a215d06b81d34bcdbbbe63f7257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Tue, 26 Sep 2023 14:58:45 -0700 Subject: [PATCH 02/33] Setup readme badges (#11) * Setup readme badges * Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5ba3991..d692e87 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Exercism GDScript Track -[![configlet](https://github.com/exercism/gdscript/workflows/configlet/badge.svg)](https://github.com/exercism/gdscript/actions?query=workflow%3Aconfiglet) [![tests](https://github.com/exercism/gdscript/workflows/test/badge.svg)](https://github.com/exercism/gdscript/actions?query=workflow%3Atest) +[![Configlet](https://github.com/exercism/gdscript/actions/workflows/configlet.yml/badge.svg)](https://github.com/exercism/gdscript/actions/workflows/configlet.yml) [![.github/workflows/test.yml](https://github.com/exercism/gdscript/actions/workflows/test.yml/badge.svg)](https://github.com/exercism/gdscript/actions/workflows/test.yml) Exercism exercises in GDScript. @@ -14,7 +14,7 @@ This command will iterate over all exercises and check to see if their exemplar/ [`configlet`](https://exercism.org/docs/building/configlet) is an Exercism-wide tool for working with tracks. You can download it by running: ```shell -$ ./bin/fetch-configlet +./bin/fetch-configlet ``` Run its [`lint` command](https://exercism.org/docs/building/configlet/lint) to verify if all exercises have all the necessary files and if config files are correct: From 4df81bf5898ab5c02b9c9f1b6353e6ce04519bc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Tue, 26 Sep 2023 15:04:02 -0700 Subject: [PATCH 03/33] Add tags (#12) --- config.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/config.json b/config.json index 8affe84..dfce2a0 100644 --- a/config.json +++ b/config.json @@ -27,5 +27,14 @@ }, "concepts": [], "key_features": [], - "tags": [] + "tags": [ + "paradigm/object_oriented", + "typing/dynamic", + "execution_mode/interpreted", + "platform/windows", + "platform/mac", + "platform/linux", + "platform/android", + "used_for/games" + ] } From 9bf646f156653b1f322d74024efd506d0b3a3d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Thu, 5 Oct 2023 13:48:37 -0700 Subject: [PATCH 04/33] [Docs]: Update RESOURCES.md (#14) * Update RESOURCES.md * Add godot engine homepage * Minor tweaks for conciseness * Update RESOURCES.md * Update RESOURCES.md --- docs/RESOURCES.md | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/docs/RESOURCES.md b/docs/RESOURCES.md index 9811f04..1d32dda 100644 --- a/docs/RESOURCES.md +++ b/docs/RESOURCES.md @@ -1,13 +1,8 @@ # Resources - - +* [Official Godot Homepage](https://godotengine.org/) +* [Official Godot Documentation](https://docs.godotengine.org/en/stable/) +* [Official Godot Q&A Platform](https://ask.godotengine.org/) +* [Official Godot Discord](https://discord.com/invite/4JBkykG) +* [r/godot on Reddit](https://www.reddit.com/r/godot/) +* [Godot on Steam](https://steamcommunity.com/app/404790) +* [Godot Forums](https://godotforums.org/) From 675a670fad71a580fb9c8a4cf90c42a5d6176bba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Oct 2023 22:55:19 +0200 Subject: [PATCH 05/33] Bump actions/checkout from 3 to 4 (#10) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 67a8ba0..149bbca 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,7 +27,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Use uses: From 170c582513da955a7a538fb1fcfa044d861567bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Mon, 16 Oct 2023 12:59:35 -0700 Subject: [PATCH 06/33] [Docs]: Update SNIPPET.txt (#15) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update SNIPPET.txt * Update docs/SNIPPET.txt Co-authored-by: Paweł Fertyk --------- Co-authored-by: Paweł Fertyk --- docs/SNIPPET.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/SNIPPET.txt b/docs/SNIPPET.txt index 4b4a4f0..ee15d49 100644 --- a/docs/SNIPPET.txt +++ b/docs/SNIPPET.txt @@ -1 +1,2 @@ -TODO: add snippet +func hello(name): + return "Hello, %s!" % name From 44073c1a11c2024780e227cdf16338cc6169febd Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Wed, 15 Nov 2023 12:46:21 +0100 Subject: [PATCH 07/33] Pin GitHub Actions workflows to a specific version (#22) --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 149bbca..d8f5b1a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,7 +27,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - name: Use uses: From ee7c5ab2832b85e1335b0ceecbccb271fde9f2a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=C2=A0Fertyk?= Date: Tue, 12 Dec 2023 18:58:32 +0100 Subject: [PATCH 08/33] Setup Hello World exercise (#3) --- .github/workflows/lint.yml | 20 +++++++++ .github/workflows/test.yml | 12 ++---- bin/verify-exercises | 42 +++++++++++-------- config.json | 21 ++++++++-- .../hello-world/.docs/instructions.md | 16 +++++++ .../practice/hello-world/.meta/config.json | 22 ++++++++++ .../practice/hello-world/.meta/example.gd | 2 + .../practice/hello-world/.meta/tests.toml | 13 ++++++ exercises/practice/hello-world/hello_world.gd | 2 + .../practice/hello-world/hello_world_test.gd | 2 + 10 files changed, 122 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/lint.yml create mode 100644 exercises/practice/hello-world/.docs/instructions.md create mode 100644 exercises/practice/hello-world/.meta/config.json create mode 100644 exercises/practice/hello-world/.meta/example.gd create mode 100644 exercises/practice/hello-world/.meta/tests.toml create mode 100644 exercises/practice/hello-world/hello_world.gd create mode 100644 exercises/practice/hello-world/hello_world_test.gd diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..9217f50 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,20 @@ +name: GDScript / Lint + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +jobs: + lint: + runs-on: ubuntu-22.04 + steps: + - name: Checkout repository + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + + - name: Setup gdtoolkit + uses: Scony/godot-gdscript-toolkit@09af1747fd66629af601b1f14d1ac24203358686 + + - name: Lint + run: gdlint exercises diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d8f5b1a..8ae56a2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ # Requires scripts: # - bin/test -name: / Test +name: GDScript / Test on: push: @@ -23,17 +23,13 @@ on: jobs: ci: - runs-on: + runs-on: ubuntu-22.04 + container: + image: exercism/gdscript-test-runner steps: - name: Checkout repository uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - name: Use - uses: - - - name: Install project dependencies - run: - - name: Verify all exercises run: bin/verify-exercises diff --git a/bin/verify-exercises b/bin/verify-exercises index 8d31328..18e83e2 100755 --- a/bin/verify-exercises +++ b/bin/verify-exercises @@ -1,28 +1,34 @@ #!/usr/bin/env bash -# Synopsis: -# Test the track's exercises. -# -# At a minimum, this file must check if the example/exemplar solution of each -# Practice/Concept Exercise passes the exercise's tests. -# -# To check this, you usually have to (temporarily) replace the exercise's solution files -# with its exemplar/example files. -# -# If your track uses skipped tests, make sure to (temporarily) enable these tests -# before running the tests. -# -# The path to the solution/example/exemplar files can be found in the exercise's -# .meta/config.json file, or possibly inferred from the exercise's directory name. +temp_dir_base=$(mktemp -d) +echo $(godot --version) -# Example: -# ./bin/test +run_test() { + slug=$(basename $1) + temp_dir=${temp_dir_base}/${slug} + mkdir -p ${temp_dir} + # Copy relevant files to the temp directory (replace solution with example) + solution_file_name="$(jq -r '.files.solution[0]' $1/.meta/config.json)" + test_file="$1/$(jq -r '.files.test[0]' $1/.meta/config.json)" + example_file="$1/$(jq -r '.files.example[0]' $1/.meta/config.json)" + cp ${test_file} ${temp_dir} + cp ${example_file} "${temp_dir}/${solution_file_name}" + # Run the tests + (cd /opt/test-runner && bin/run.sh $slug $temp_dir $temp_dir) || exit 1 + # Check status + test_status="$(jq -r '.status' $temp_dir/results.json)" + if [ "$test_status" != "pass" ]; then + echo "Tests for $slug have failed:" + cat $temp_dir/results.json + exit 1 + fi +} # Verify the Concept Exercises for concept_exercise_dir in ./exercises/concept/*/; do if [ -d $concept_exercise_dir ]; then echo "Checking $(basename "${concept_exercise_dir}") exercise..." - # TODO: run command to verify that the exemplar solution passes the tests + run_test $concept_exercise_dir fi done @@ -30,6 +36,6 @@ done for practice_exercise_dir in ./exercises/practice/*/; do if [ -d $practice_exercise_dir ]; then echo "Checking $(basename "${practice_exercise_dir}") exercise..." - # TODO: run command to verify that the example solution passes the tests + run_test $practice_exercise_dir fi done diff --git a/config.json b/config.json index dfce2a0..49cfddf 100644 --- a/config.json +++ b/config.json @@ -4,17 +4,20 @@ "active": false, "status": { "concept_exercises": false, - "test_runner": false, + "test_runner": true, "representer": false, "analyzer": false }, - "blurb": "TODO: add blurb", + "blurb": "GDScript is a high-level, object-oriented, imperative, and gradually typed programming language built for Godot. It uses an indentation-based syntax similar to languages like Python. Its goal is to be optimized for and tightly integrated with Godot Engine, allowing great flexibility for content creation and integration.", "version": 3, "online_editor": { - "indent_style": "space", + "indent_style": "tab", "indent_size": 4, "highlightjs_language": "gdscript" }, + "test_runner": { + "average_run_time": 2 + }, "files": { "solution": ["%{snake_slug}.gd"], "test": ["%{snake_slug}_test.gd"], @@ -23,12 +26,22 @@ }, "exercises": { "concept": [], - "practice": [] + "practice": [ + { + "uuid": "1adfc420-46f2-4d5b-93a3-165ede1fcd9f", + "slug": "hello-world", + "name": "Hello World", + "practices": [], + "prerequisites": [], + "difficulty": 1 + } + ] }, "concepts": [], "key_features": [], "tags": [ "paradigm/object_oriented", + "typing/static", "typing/dynamic", "execution_mode/interpreted", "platform/windows", diff --git a/exercises/practice/hello-world/.docs/instructions.md b/exercises/practice/hello-world/.docs/instructions.md new file mode 100644 index 0000000..c9570e4 --- /dev/null +++ b/exercises/practice/hello-world/.docs/instructions.md @@ -0,0 +1,16 @@ +# Instructions + +The classical introductory exercise. +Just say "Hello, World!". + +["Hello, World!"][hello-world] is the traditional first program for beginning programming in a new language or environment. + +The objectives are simple: + +- Modify the provided code so that it produces the string "Hello, World!". +- Run the test suite and make sure that it succeeds. +- Submit your solution and check it at the website. + +If everything goes well, you will be ready to fetch your first real exercise. + +[hello-world]: https://en.wikipedia.org/wiki/%22Hello,_world!%22_program diff --git a/exercises/practice/hello-world/.meta/config.json b/exercises/practice/hello-world/.meta/config.json new file mode 100644 index 0000000..0a09605 --- /dev/null +++ b/exercises/practice/hello-world/.meta/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "pfertyk" + ], + "contributors": [ + "BNAndras" + ], + "files": { + "solution": [ + "hello_world.gd" + ], + "test": [ + "hello_world_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "The classical introductory exercise. Just say \"Hello, World!\".", + "source": "This is an exercise to introduce users to using Exercism", + "source_url": "https://en.wikipedia.org/wiki/%22Hello,_world!%22_program" +} diff --git a/exercises/practice/hello-world/.meta/example.gd b/exercises/practice/hello-world/.meta/example.gd new file mode 100644 index 0000000..ac88163 --- /dev/null +++ b/exercises/practice/hello-world/.meta/example.gd @@ -0,0 +1,2 @@ +func hello(): + return "Hello, World!" diff --git a/exercises/practice/hello-world/.meta/tests.toml b/exercises/practice/hello-world/.meta/tests.toml new file mode 100644 index 0000000..73466d6 --- /dev/null +++ b/exercises/practice/hello-world/.meta/tests.toml @@ -0,0 +1,13 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[af9ffe10-dc13-42d8-a742-e7bdafac449d] +description = "Say Hi!" diff --git a/exercises/practice/hello-world/hello_world.gd b/exercises/practice/hello-world/hello_world.gd new file mode 100644 index 0000000..1338b51 --- /dev/null +++ b/exercises/practice/hello-world/hello_world.gd @@ -0,0 +1,2 @@ +func hello(): + return "Goodbye, Mars!" diff --git a/exercises/practice/hello-world/hello_world_test.gd b/exercises/practice/hello-world/hello_world_test.gd new file mode 100644 index 0000000..5655ada --- /dev/null +++ b/exercises/practice/hello-world/hello_world_test.gd @@ -0,0 +1,2 @@ +func test_hello_world(solution_script): + return ["Hello, World!", solution_script.hello()] From c8bce940d8515fa533869addae4d736cec0100f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Wed, 13 Dec 2023 11:35:58 -0800 Subject: [PATCH 09/33] Add gdlint config (#23) --- .gdlintrc | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 .gdlintrc diff --git a/.gdlintrc b/.gdlintrc new file mode 100644 index 0000000..9e39567 --- /dev/null +++ b/.gdlintrc @@ -0,0 +1,49 @@ +class-definitions-order: +- tools +- classnames +- extends +- docstrings +- signals +- enums +- consts +- exports +- pubvars +- prvvars +- onreadypubvars +- onreadyprvvars +- staticvars +- others +class-load-variable-name: (([A-Z][a-z0-9]*)+|_?[a-z][a-z0-9]*(_[a-z0-9]+)*) +class-name: ([A-Z][a-z0-9]*)+ +class-variable-name: _?[a-z][a-z0-9]*(_[a-z0-9]+)* +comparison-with-itself: null +constant-name: _?[A-Z][A-Z0-9]*(_[A-Z0-9]+)* +disable: [ + unused-argument, +] +duplicated-load: null +enum-element-name: '[A-Z][A-Z0-9]*(_[A-Z0-9]+)*' +enum-name: ([A-Z][a-z0-9]*)+ +excluded_directories: !!set + .git: null +expression-not-assigned: null +function-argument-name: _?[a-z][a-z0-9]*(_[a-z0-9]+)* +function-arguments-number: 10 +function-preload-variable-name: ([A-Z][a-z0-9]*)+ +function-variable-name: '[a-z][a-z0-9]*(_[a-z0-9]+)*' +load-constant-name: (([A-Z][a-z0-9]*)+|_?[A-Z][A-Z0-9]*(_[A-Z0-9]+)*) +loop-variable-name: _?[a-z][a-z0-9]*(_[a-z0-9]+)* +max-file-lines: 1000 +max-line-length: 100 +max-public-methods: 20 +max-returns: 6 +mixed-tabs-and-spaces: null +no-elif-return: null +no-else-return: null +private-method-call: null +signal-name: '[a-z][a-z0-9]*(_[a-z0-9]+)*' +sub-class-name: _?([A-Z][a-z0-9]*)+ +tab-characters: 1 +trailing-whitespace: null +unnecessary-pass: null +unused-argument: null From 73709be0a6bdfd4fd4a9cb1abe93f11c3a46c86b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Sun, 17 Dec 2023 05:01:43 -0800 Subject: [PATCH 10/33] [New exercise]: leap (#13) * Setup leap exercise files * Fix typos * Break up long test cases * Add gdlint config (cherry picked from commit 310b2a508c7663eca0dd32dbd68d832e0ac2ee31) * Update test suite --- config.json | 8 ++++ exercises/practice/leap/.docs/instructions.md | 22 +++++++++++ exercises/practice/leap/.meta/config.json | 19 ++++++++++ exercises/practice/leap/.meta/example.gd | 2 + exercises/practice/leap/.meta/tests.toml | 37 +++++++++++++++++++ exercises/practice/leap/leap.gd | 2 + exercises/practice/leap/leap_test.gd | 26 +++++++++++++ 7 files changed, 116 insertions(+) create mode 100644 exercises/practice/leap/.docs/instructions.md create mode 100644 exercises/practice/leap/.meta/config.json create mode 100644 exercises/practice/leap/.meta/example.gd create mode 100644 exercises/practice/leap/.meta/tests.toml create mode 100644 exercises/practice/leap/leap.gd create mode 100644 exercises/practice/leap/leap_test.gd diff --git a/config.json b/config.json index 49cfddf..b6decc5 100644 --- a/config.json +++ b/config.json @@ -34,6 +34,14 @@ "practices": [], "prerequisites": [], "difficulty": 1 + }, + { + "uuid": "c3b37c54-cc4e-49a5-a869-cd7700b0e448", + "slug": "leap", + "name": "Leap", + "practices": [], + "prerequisites": [], + "difficulty": 1 } ] }, diff --git a/exercises/practice/leap/.docs/instructions.md b/exercises/practice/leap/.docs/instructions.md new file mode 100644 index 0000000..a83826b --- /dev/null +++ b/exercises/practice/leap/.docs/instructions.md @@ -0,0 +1,22 @@ +# Instructions + +Given a year, report if it is a leap year. + +The tricky thing here is that a leap year in the Gregorian calendar occurs: + +```text +on every year that is evenly divisible by 4 + except every year that is evenly divisible by 100 + unless the year is also evenly divisible by 400 +``` + +For example, 1997 is not a leap year, but 1996 is. +1900 is not a leap year, but 2000 is. + +## Notes + +Though our exercise adopts some very simple rules, there is more to learn! + +For a delightful, four minute explanation of the whole leap year phenomenon, go watch [this youtube video][video]. + +[video]: https://www.youtube.com/watch?v=xX96xng7sAE diff --git a/exercises/practice/leap/.meta/config.json b/exercises/practice/leap/.meta/config.json new file mode 100644 index 0000000..a07a6f1 --- /dev/null +++ b/exercises/practice/leap/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "leap.gd" + ], + "test": [ + "leap_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Given a year, report if it is a leap year.", + "source": "CodeRanch Cattle Drive, Assignment 3", + "source_url": "https://coderanch.com/t/718816/Leap" +} diff --git a/exercises/practice/leap/.meta/example.gd b/exercises/practice/leap/.meta/example.gd new file mode 100644 index 0000000..db89dd9 --- /dev/null +++ b/exercises/practice/leap/.meta/example.gd @@ -0,0 +1,2 @@ +func leap(year): + return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) diff --git a/exercises/practice/leap/.meta/tests.toml b/exercises/practice/leap/.meta/tests.toml new file mode 100644 index 0000000..ce6ba32 --- /dev/null +++ b/exercises/practice/leap/.meta/tests.toml @@ -0,0 +1,37 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[6466b30d-519c-438e-935d-388224ab5223] +description = "year not divisible by 4 in common year" + +[ac227e82-ee82-4a09-9eb6-4f84331ffdb0] +description = "year divisible by 2, not divisible by 4 in common year" + +[4fe9b84c-8e65-489e-970b-856d60b8b78e] +description = "year divisible by 4, not divisible by 100 in leap year" + +[7fc6aed7-e63c-48f5-ae05-5fe182f60a5d] +description = "year divisible by 4 and 5 is still a leap year" + +[78a7848f-9667-4192-ae53-87b30c9a02dd] +description = "year divisible by 100, not divisible by 400 in common year" + +[9d70f938-537c-40a6-ba19-f50739ce8bac] +description = "year divisible by 100 but not by 3 is still not a leap year" + +[42ee56ad-d3e6-48f1-8e3f-c84078d916fc] +description = "year divisible by 400 is leap year" + +[57902c77-6fe9-40de-8302-587b5c27121e] +description = "year divisible by 400 but not by 125 is still a leap year" + +[c30331f6-f9f6-4881-ad38-8ca8c12520c1] +description = "year divisible by 200, not divisible by 400 in common year" diff --git a/exercises/practice/leap/leap.gd b/exercises/practice/leap/leap.gd new file mode 100644 index 0000000..bd45d34 --- /dev/null +++ b/exercises/practice/leap/leap.gd @@ -0,0 +1,2 @@ +func leap(year): + pass diff --git a/exercises/practice/leap/leap_test.gd b/exercises/practice/leap/leap_test.gd new file mode 100644 index 0000000..e2d298c --- /dev/null +++ b/exercises/practice/leap/leap_test.gd @@ -0,0 +1,26 @@ +func test_year_not_divisible_by_4(solution_script): + return [false, solution_script.leap(2015)] + +func test_year_divisible_by_2_not_4(solution_script): + return [false, solution_script.leap(1970)] + +func test_year_divisible_by_4_not_100(solution_script): + return [true, solution_script.leap(1996)] + +func test_year_divisible_by_4_and_5(solution_script): + return [true, solution_script.leap(1960)] + +func test_year_divisible_by_100_not_400(solution_script): + return [false, solution_script.leap(2100)] + +func test_year_divisible_by_100_not_3(solution_script): + return [false, solution_script.leap(1900)] + +func test_year_divisible_by_400(solution_script): + return [true, solution_script.leap(2000)] + +func test_year_divisible_by_400_not_125(solution_script): + return [true, solution_script.leap(2400)] + +func test_year_divisible_by_200_not_400(solution_script): + return [false, solution_script.leap(1800)] From 15b69e05d3ea60871cbed3ea30eb20a68660d0c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Mon, 18 Dec 2023 10:44:41 -0800 Subject: [PATCH 11/33] [New exercise]: resistor-color (#16) * Add resistor-color * Apply code review * Formatting --- config.json | 8 ++++ .../resistor-color/.docs/instructions.md | 39 +++++++++++++++++++ .../practice/resistor-color/.meta/config.json | 19 +++++++++ .../practice/resistor-color/.meta/example.gd | 18 +++++++++ .../practice/resistor-color/.meta/tests.toml | 22 +++++++++++ .../practice/resistor-color/resistor_color.gd | 6 +++ .../resistor-color/resistor_color_test.gd | 26 +++++++++++++ 7 files changed, 138 insertions(+) create mode 100644 exercises/practice/resistor-color/.docs/instructions.md create mode 100644 exercises/practice/resistor-color/.meta/config.json create mode 100644 exercises/practice/resistor-color/.meta/example.gd create mode 100644 exercises/practice/resistor-color/.meta/tests.toml create mode 100644 exercises/practice/resistor-color/resistor_color.gd create mode 100644 exercises/practice/resistor-color/resistor_color_test.gd diff --git a/config.json b/config.json index b6decc5..003b658 100644 --- a/config.json +++ b/config.json @@ -42,6 +42,14 @@ "practices": [], "prerequisites": [], "difficulty": 1 + }, + { + "slug": "resistor-color", + "name": "Resistor Color", + "uuid": "f8afa182-aca3-4464-96b7-9eb7f8d55449", + "practices": [], + "prerequisites": [], + "difficulty": 2 } ] }, diff --git a/exercises/practice/resistor-color/.docs/instructions.md b/exercises/practice/resistor-color/.docs/instructions.md new file mode 100644 index 0000000..646c143 --- /dev/null +++ b/exercises/practice/resistor-color/.docs/instructions.md @@ -0,0 +1,39 @@ +# Instructions + +If you want to build something using a Raspberry Pi, you'll probably use _resistors_. +For this exercise, you need to know two things about them: + +- Each resistor has a resistance value. +- Resistors are small - so small in fact that if you printed the resistance value on them, it would be hard to read. + +To get around this problem, manufacturers print color-coded bands onto the resistors to denote their resistance values. +Each band has a position and a numeric value. + +The first 2 bands of a resistor have a simple encoding scheme: each color maps to a single number. + +In this exercise you are going to create a helpful program so that you don't have to remember the values of the bands. + +These colors are encoded as follows: + +- Black: 0 +- Brown: 1 +- Red: 2 +- Orange: 3 +- Yellow: 4 +- Green: 5 +- Blue: 6 +- Violet: 7 +- Grey: 8 +- White: 9 + +The goal of this exercise is to create a way: + +- to look up the numerical value associated with a particular color band +- to list the different band colors + +Mnemonics map the colors to the numbers, that, when stored as an array, happen to map to their index in the array: +Better Be Right Or Your Great Big Values Go Wrong. + +More information on the color encoding of resistors can be found in the [Electronic color code Wikipedia article][e-color-code]. + +[e-color-code]: https://en.wikipedia.org/wiki/Electronic_color_code diff --git a/exercises/practice/resistor-color/.meta/config.json b/exercises/practice/resistor-color/.meta/config.json new file mode 100644 index 0000000..af8dec4 --- /dev/null +++ b/exercises/practice/resistor-color/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "resistor_color.gd" + ], + "test": [ + "resistor_color_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Convert a resistor band's color to its numeric representation.", + "source": "Maud de Vries, Erik Schierboom", + "source_url": "https://github.com/exercism/problem-specifications/issues/1458" +} diff --git a/exercises/practice/resistor-color/.meta/example.gd b/exercises/practice/resistor-color/.meta/example.gd new file mode 100644 index 0000000..b0b34e3 --- /dev/null +++ b/exercises/practice/resistor-color/.meta/example.gd @@ -0,0 +1,18 @@ +const COLORS = ["black", + "brown", + "red", + "orange", + "yellow", + "green", + "blue", + "violet", + "grey", + "white"] + + +func color_code(color): + return COLORS.find(color) + + +func colors(): + return COLORS diff --git a/exercises/practice/resistor-color/.meta/tests.toml b/exercises/practice/resistor-color/.meta/tests.toml new file mode 100644 index 0000000..9d4ee97 --- /dev/null +++ b/exercises/practice/resistor-color/.meta/tests.toml @@ -0,0 +1,22 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[49eb31c5-10a8-4180-9f7f-fea632ab87ef] +description = "Color codes -> Black" + +[0a4df94b-92da-4579-a907-65040ce0b3fc] +description = "Color codes -> White" + +[5f81608d-f36f-4190-8084-f45116b6f380] +description = "Color codes -> Orange" + +[581d68fa-f968-4be2-9f9d-880f2fb73cf7] +description = "Colors" diff --git a/exercises/practice/resistor-color/resistor_color.gd b/exercises/practice/resistor-color/resistor_color.gd new file mode 100644 index 0000000..b1e36f3 --- /dev/null +++ b/exercises/practice/resistor-color/resistor_color.gd @@ -0,0 +1,6 @@ +func color_code(color): + pass + + +func colors(): + pass diff --git a/exercises/practice/resistor-color/resistor_color_test.gd b/exercises/practice/resistor-color/resistor_color_test.gd new file mode 100644 index 0000000..e4a8eeb --- /dev/null +++ b/exercises/practice/resistor-color/resistor_color_test.gd @@ -0,0 +1,26 @@ +func test_color_codes_black(solution_script): + return [0, solution_script.color_code("black")] + + +func test_color_codes_white(solution_script): + return [9, solution_script.color_code("white")] + + +func test_color_codes_orange(solution_script): + return [3, solution_script.color_code("orange")] + + +func test_colors(solution_script): + return [ + ["black", + "brown", + "red", + "orange", + "yellow", + "green", + "blue", + "violet", + "grey", + "white"], + solution_script.colors() + ] From 32b13555f42d216e9e0ca7074b88fe0899ffce3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:11:30 -0800 Subject: [PATCH 12/33] [New exercise]: resistor-color-duo (#17) * Add resistor-color-duo * Fix example * Formatting * Formatting --- config.json | 8 ++++ .../resistor-color-duo/.docs/instructions.md | 33 +++++++++++++++ .../resistor-color-duo/.meta/config.json | 19 +++++++++ .../resistor-color-duo/.meta/example.gd | 16 ++++++++ .../resistor-color-duo/.meta/tests.toml | 31 ++++++++++++++ .../resistor-color-duo/resistor_color_duo.gd | 2 + .../resistor_color_duo_test.gd | 40 +++++++++++++++++++ 7 files changed, 149 insertions(+) create mode 100644 exercises/practice/resistor-color-duo/.docs/instructions.md create mode 100644 exercises/practice/resistor-color-duo/.meta/config.json create mode 100644 exercises/practice/resistor-color-duo/.meta/example.gd create mode 100644 exercises/practice/resistor-color-duo/.meta/tests.toml create mode 100644 exercises/practice/resistor-color-duo/resistor_color_duo.gd create mode 100644 exercises/practice/resistor-color-duo/resistor_color_duo_test.gd diff --git a/config.json b/config.json index 003b658..a7e1e0e 100644 --- a/config.json +++ b/config.json @@ -35,6 +35,14 @@ "prerequisites": [], "difficulty": 1 }, + { + "slug": "resistor-color-duo", + "name": "Resistor Color Duo", + "uuid": "c15ce044-1a62-45eb-86a2-079554cbd2c2", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "uuid": "c3b37c54-cc4e-49a5-a869-cd7700b0e448", "slug": "leap", diff --git a/exercises/practice/resistor-color-duo/.docs/instructions.md b/exercises/practice/resistor-color-duo/.docs/instructions.md new file mode 100644 index 0000000..bdcd549 --- /dev/null +++ b/exercises/practice/resistor-color-duo/.docs/instructions.md @@ -0,0 +1,33 @@ +# Instructions + +If you want to build something using a Raspberry Pi, you'll probably use _resistors_. +For this exercise, you need to know two things about them: + +- Each resistor has a resistance value. +- Resistors are small - so small in fact that if you printed the resistance value on them, it would be hard to read. + +To get around this problem, manufacturers print color-coded bands onto the resistors to denote their resistance values. +Each band has a position and a numeric value. + +The first 2 bands of a resistor have a simple encoding scheme: each color maps to a single number. +For example, if they printed a brown band (value 1) followed by a green band (value 5), it would translate to the number 15. + +In this exercise you are going to create a helpful program so that you don't have to remember the values of the bands. +The program will take color names as input and output a two digit number, even if the input is more than two colors! + +The band colors are encoded as follows: + +- Black: 0 +- Brown: 1 +- Red: 2 +- Orange: 3 +- Yellow: 4 +- Green: 5 +- Blue: 6 +- Violet: 7 +- Grey: 8 +- White: 9 + +From the example above: +brown-green should return 15 +brown-green-violet should return 15 too, ignoring the third color. diff --git a/exercises/practice/resistor-color-duo/.meta/config.json b/exercises/practice/resistor-color-duo/.meta/config.json new file mode 100644 index 0000000..f65d615 --- /dev/null +++ b/exercises/practice/resistor-color-duo/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "resistor_color_duo.gd" + ], + "test": [ + "resistor_color_duo_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Convert color codes, as used on resistors, to a numeric value.", + "source": "Maud de Vries, Erik Schierboom", + "source_url": "https://github.com/exercism/problem-specifications/issues/1464" +} diff --git a/exercises/practice/resistor-color-duo/.meta/example.gd b/exercises/practice/resistor-color-duo/.meta/example.gd new file mode 100644 index 0000000..5858c86 --- /dev/null +++ b/exercises/practice/resistor-color-duo/.meta/example.gd @@ -0,0 +1,16 @@ +const COLORS = ["black", + "brown", + "red", + "orange", + "yellow", + "green", + "blue", + "violet", + "grey", + "white"] + + +func color_code(colors): + var tens = colors[0] + var ones = colors[1] + return COLORS.find(tens) * 10 + COLORS.find(ones) diff --git a/exercises/practice/resistor-color-duo/.meta/tests.toml b/exercises/practice/resistor-color-duo/.meta/tests.toml new file mode 100644 index 0000000..9036fc7 --- /dev/null +++ b/exercises/practice/resistor-color-duo/.meta/tests.toml @@ -0,0 +1,31 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[ce11995a-5b93-4950-a5e9-93423693b2fc] +description = "Brown and black" + +[7bf82f7a-af23-48ba-a97d-38d59406a920] +description = "Blue and grey" + +[f1886361-fdfd-4693-acf8-46726fe24e0c] +description = "Yellow and violet" + +[b7a6cbd2-ae3c-470a-93eb-56670b305640] +description = "White and red" + +[77a8293d-2a83-4016-b1af-991acc12b9fe] +description = "Orange and orange" + +[0c4fb44f-db7c-4d03-afa8-054350f156a8] +description = "Ignore additional colors" + +[4a8ceec5-0ab4-4904-88a4-daf953a5e818] +description = "Black and brown, one-digit" diff --git a/exercises/practice/resistor-color-duo/resistor_color_duo.gd b/exercises/practice/resistor-color-duo/resistor_color_duo.gd new file mode 100644 index 0000000..41c7b64 --- /dev/null +++ b/exercises/practice/resistor-color-duo/resistor_color_duo.gd @@ -0,0 +1,2 @@ +func color_code(colors): + pass diff --git a/exercises/practice/resistor-color-duo/resistor_color_duo_test.gd b/exercises/practice/resistor-color-duo/resistor_color_duo_test.gd new file mode 100644 index 0000000..6eef7ef --- /dev/null +++ b/exercises/practice/resistor-color-duo/resistor_color_duo_test.gd @@ -0,0 +1,40 @@ +func test_brown_and_black(solution_script): + var colors = ["brown", "black"] + var expected = 10 + return [expected, solution_script.color_code(colors)] + + +func test_blue_and_grey(solution_script): + var colors = ["blue", "grey"] + var expected = 68 + return [expected, solution_script.color_code(colors)] + + +func test_yellow_and_violet(solution_script): + var colors = ["yellow", "violet"] + var expected = 47 + return [expected, solution_script.color_code(colors)] + + +func test_white_and_red(solution_script): + var colors = ["white", "red"] + var expected = 92 + return [expected, solution_script.color_code(colors)] + + +func test_orange_and_orange(solution_script): + var colors = ["orange", "orange"] + var expected = 33 + return [expected, solution_script.color_code(colors)] + + +func test_ignore_additional_colors(solution_script): + var colors = ["green", "brown", "orange"] + var expected = 51 + return [expected, solution_script.color_code(colors)] + + +func test_black_and_brown_one_digit(solution_script): + var colors = ["black", "brown"] + var expected = 1 + return [expected, solution_script.color_code(colors)] From 057131a8a81ade141a6429da0729c8f5f6082f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=C2=A0Fertyk?= Date: Tue, 26 Dec 2023 22:25:09 +0100 Subject: [PATCH 13/33] Fix indentation in exercise files (#27) --- exercises/practice/leap/.meta/example.gd | 2 +- exercises/practice/leap/leap.gd | 2 +- exercises/practice/leap/leap_test.gd | 24 +++++++---- .../resistor-color-duo/.meta/example.gd | 28 +++++++------ .../resistor-color-duo/resistor_color_duo.gd | 2 +- .../resistor_color_duo_test.gd | 42 +++++++++---------- .../practice/resistor-color/.meta/example.gd | 26 ++++++------ .../practice/resistor-color/resistor_color.gd | 4 +- .../resistor-color/resistor_color_test.gd | 30 ++++++------- 9 files changed, 86 insertions(+), 74 deletions(-) diff --git a/exercises/practice/leap/.meta/example.gd b/exercises/practice/leap/.meta/example.gd index db89dd9..07378d1 100644 --- a/exercises/practice/leap/.meta/example.gd +++ b/exercises/practice/leap/.meta/example.gd @@ -1,2 +1,2 @@ func leap(year): - return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) + return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) diff --git a/exercises/practice/leap/leap.gd b/exercises/practice/leap/leap.gd index bd45d34..eb60b2f 100644 --- a/exercises/practice/leap/leap.gd +++ b/exercises/practice/leap/leap.gd @@ -1,2 +1,2 @@ func leap(year): - pass + pass diff --git a/exercises/practice/leap/leap_test.gd b/exercises/practice/leap/leap_test.gd index e2d298c..8463fdd 100644 --- a/exercises/practice/leap/leap_test.gd +++ b/exercises/practice/leap/leap_test.gd @@ -1,26 +1,34 @@ func test_year_not_divisible_by_4(solution_script): return [false, solution_script.leap(2015)] + func test_year_divisible_by_2_not_4(solution_script): - return [false, solution_script.leap(1970)] + return [false, solution_script.leap(1970)] + func test_year_divisible_by_4_not_100(solution_script): - return [true, solution_script.leap(1996)] + return [true, solution_script.leap(1996)] + func test_year_divisible_by_4_and_5(solution_script): - return [true, solution_script.leap(1960)] + return [true, solution_script.leap(1960)] + func test_year_divisible_by_100_not_400(solution_script): - return [false, solution_script.leap(2100)] + return [false, solution_script.leap(2100)] + func test_year_divisible_by_100_not_3(solution_script): - return [false, solution_script.leap(1900)] + return [false, solution_script.leap(1900)] + func test_year_divisible_by_400(solution_script): - return [true, solution_script.leap(2000)] + return [true, solution_script.leap(2000)] + func test_year_divisible_by_400_not_125(solution_script): - return [true, solution_script.leap(2400)] + return [true, solution_script.leap(2400)] + func test_year_divisible_by_200_not_400(solution_script): - return [false, solution_script.leap(1800)] + return [false, solution_script.leap(1800)] diff --git a/exercises/practice/resistor-color-duo/.meta/example.gd b/exercises/practice/resistor-color-duo/.meta/example.gd index 5858c86..952da12 100644 --- a/exercises/practice/resistor-color-duo/.meta/example.gd +++ b/exercises/practice/resistor-color-duo/.meta/example.gd @@ -1,16 +1,18 @@ -const COLORS = ["black", - "brown", - "red", - "orange", - "yellow", - "green", - "blue", - "violet", - "grey", - "white"] +const COLORS = [ + "black", + "brown", + "red", + "orange", + "yellow", + "green", + "blue", + "violet", + "grey", + "white" +] func color_code(colors): - var tens = colors[0] - var ones = colors[1] - return COLORS.find(tens) * 10 + COLORS.find(ones) + var tens = colors[0] + var ones = colors[1] + return COLORS.find(tens) * 10 + COLORS.find(ones) diff --git a/exercises/practice/resistor-color-duo/resistor_color_duo.gd b/exercises/practice/resistor-color-duo/resistor_color_duo.gd index 41c7b64..087a9bb 100644 --- a/exercises/practice/resistor-color-duo/resistor_color_duo.gd +++ b/exercises/practice/resistor-color-duo/resistor_color_duo.gd @@ -1,2 +1,2 @@ func color_code(colors): - pass + pass diff --git a/exercises/practice/resistor-color-duo/resistor_color_duo_test.gd b/exercises/practice/resistor-color-duo/resistor_color_duo_test.gd index 6eef7ef..938f4b1 100644 --- a/exercises/practice/resistor-color-duo/resistor_color_duo_test.gd +++ b/exercises/practice/resistor-color-duo/resistor_color_duo_test.gd @@ -1,40 +1,40 @@ func test_brown_and_black(solution_script): - var colors = ["brown", "black"] - var expected = 10 - return [expected, solution_script.color_code(colors)] + var colors = ["brown", "black"] + var expected = 10 + return [expected, solution_script.color_code(colors)] func test_blue_and_grey(solution_script): - var colors = ["blue", "grey"] - var expected = 68 - return [expected, solution_script.color_code(colors)] + var colors = ["blue", "grey"] + var expected = 68 + return [expected, solution_script.color_code(colors)] func test_yellow_and_violet(solution_script): - var colors = ["yellow", "violet"] - var expected = 47 - return [expected, solution_script.color_code(colors)] + var colors = ["yellow", "violet"] + var expected = 47 + return [expected, solution_script.color_code(colors)] func test_white_and_red(solution_script): - var colors = ["white", "red"] - var expected = 92 - return [expected, solution_script.color_code(colors)] + var colors = ["white", "red"] + var expected = 92 + return [expected, solution_script.color_code(colors)] func test_orange_and_orange(solution_script): - var colors = ["orange", "orange"] - var expected = 33 - return [expected, solution_script.color_code(colors)] + var colors = ["orange", "orange"] + var expected = 33 + return [expected, solution_script.color_code(colors)] func test_ignore_additional_colors(solution_script): - var colors = ["green", "brown", "orange"] - var expected = 51 - return [expected, solution_script.color_code(colors)] + var colors = ["green", "brown", "orange"] + var expected = 51 + return [expected, solution_script.color_code(colors)] func test_black_and_brown_one_digit(solution_script): - var colors = ["black", "brown"] - var expected = 1 - return [expected, solution_script.color_code(colors)] + var colors = ["black", "brown"] + var expected = 1 + return [expected, solution_script.color_code(colors)] diff --git a/exercises/practice/resistor-color/.meta/example.gd b/exercises/practice/resistor-color/.meta/example.gd index b0b34e3..0551d20 100644 --- a/exercises/practice/resistor-color/.meta/example.gd +++ b/exercises/practice/resistor-color/.meta/example.gd @@ -1,18 +1,20 @@ -const COLORS = ["black", - "brown", - "red", - "orange", - "yellow", - "green", - "blue", - "violet", - "grey", - "white"] +const COLORS = [ + "black", + "brown", + "red", + "orange", + "yellow", + "green", + "blue", + "violet", + "grey", + "white" +] func color_code(color): - return COLORS.find(color) + return COLORS.find(color) func colors(): - return COLORS + return COLORS diff --git a/exercises/practice/resistor-color/resistor_color.gd b/exercises/practice/resistor-color/resistor_color.gd index b1e36f3..fffbe9b 100644 --- a/exercises/practice/resistor-color/resistor_color.gd +++ b/exercises/practice/resistor-color/resistor_color.gd @@ -1,6 +1,6 @@ func color_code(color): - pass + pass func colors(): - pass + pass diff --git a/exercises/practice/resistor-color/resistor_color_test.gd b/exercises/practice/resistor-color/resistor_color_test.gd index e4a8eeb..787befb 100644 --- a/exercises/practice/resistor-color/resistor_color_test.gd +++ b/exercises/practice/resistor-color/resistor_color_test.gd @@ -3,24 +3,24 @@ func test_color_codes_black(solution_script): func test_color_codes_white(solution_script): - return [9, solution_script.color_code("white")] + return [9, solution_script.color_code("white")] func test_color_codes_orange(solution_script): - return [3, solution_script.color_code("orange")] + return [3, solution_script.color_code("orange")] func test_colors(solution_script): - return [ - ["black", - "brown", - "red", - "orange", - "yellow", - "green", - "blue", - "violet", - "grey", - "white"], - solution_script.colors() - ] + var colors = [ + "black", + "brown", + "red", + "orange", + "yellow", + "green", + "blue", + "violet", + "grey", + "white" + ] + return [colors, solution_script.colors()] From e0cc06cd19b3bf03492f059a356e6ab98e6af6ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Tue, 26 Dec 2023 13:46:55 -0800 Subject: [PATCH 14/33] [New exercise]: pangram (#18) * Add pangram exercise * Reformat using tabs --- .gdlintrc | 1 + config.json | 8 +++ .../practice/pangram/.docs/instructions.md | 8 +++ .../practice/pangram/.docs/introduction.md | 16 ++++++ exercises/practice/pangram/.meta/config.json | 19 +++++++ exercises/practice/pangram/.meta/example.gd | 10 ++++ exercises/practice/pangram/.meta/tests.toml | 45 +++++++++++++++ exercises/practice/pangram/pangram.gd | 2 + exercises/practice/pangram/pangram_test.gd | 57 +++++++++++++++++++ 9 files changed, 166 insertions(+) create mode 100644 exercises/practice/pangram/.docs/instructions.md create mode 100644 exercises/practice/pangram/.docs/introduction.md create mode 100644 exercises/practice/pangram/.meta/config.json create mode 100644 exercises/practice/pangram/.meta/example.gd create mode 100644 exercises/practice/pangram/.meta/tests.toml create mode 100644 exercises/practice/pangram/pangram.gd create mode 100644 exercises/practice/pangram/pangram_test.gd diff --git a/.gdlintrc b/.gdlintrc index 9e39567..270cc85 100644 --- a/.gdlintrc +++ b/.gdlintrc @@ -20,6 +20,7 @@ comparison-with-itself: null constant-name: _?[A-Z][A-Z0-9]*(_[A-Z0-9]+)* disable: [ unused-argument, + max-line-length, ] duplicated-load: null enum-element-name: '[A-Z][A-Z0-9]*(_[A-Z0-9]+)*' diff --git a/config.json b/config.json index a7e1e0e..6d1927b 100644 --- a/config.json +++ b/config.json @@ -58,6 +58,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "pangram", + "name": "Pangram", + "uuid": "385f681c-2b7d-4f32-9662-74b7aaac172b", + "practices": [], + "prerequisites": [], + "difficulty": 2 } ] }, diff --git a/exercises/practice/pangram/.docs/instructions.md b/exercises/practice/pangram/.docs/instructions.md new file mode 100644 index 0000000..817c872 --- /dev/null +++ b/exercises/practice/pangram/.docs/instructions.md @@ -0,0 +1,8 @@ +# Instructions + +Your task is to figure out if a sentence is a pangram. + +A pangram is a sentence using every letter of the alphabet at least once. +It is case insensitive, so it doesn't matter if a letter is lower-case (e.g. `k`) or upper-case (e.g. `K`). + +For this exercise, a sentence is a pangram if it contains each of the 26 letters in the English alphabet. diff --git a/exercises/practice/pangram/.docs/introduction.md b/exercises/practice/pangram/.docs/introduction.md new file mode 100644 index 0000000..d38fa34 --- /dev/null +++ b/exercises/practice/pangram/.docs/introduction.md @@ -0,0 +1,16 @@ +# Introduction + +You work for a company that sells fonts through their website. +They'd like to show a different sentence each time someone views a font on their website. +To give a comprehensive sense of the font, the random sentences should use **all** the letters in the English alphabet. + +They're running a competition to get suggestions for sentences that they can use. +You're in charge of checking the submissions to see if they are valid. + +```exercism/note +Pangram comes from Greek, παν γράμμα, pan gramma, which means "every letter". + +The best known English pangram is: + +> The quick brown fox jumps over the lazy dog. +``` diff --git a/exercises/practice/pangram/.meta/config.json b/exercises/practice/pangram/.meta/config.json new file mode 100644 index 0000000..f6d0f78 --- /dev/null +++ b/exercises/practice/pangram/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "pangram.gd" + ], + "test": [ + "pangram_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Determine if a sentence is a pangram.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Pangram" +} diff --git a/exercises/practice/pangram/.meta/example.gd b/exercises/practice/pangram/.meta/example.gd new file mode 100644 index 0000000..7546069 --- /dev/null +++ b/exercises/practice/pangram/.meta/example.gd @@ -0,0 +1,10 @@ +var lowercase = "abcdefghijklmnopqrstuvwxyz".to_utf8_buffer() + + +func is_pangram(sentence): + var bytes = sentence.to_lower().to_utf8_buffer() + var seen = {} + for byte in bytes: + if byte >= 97 and byte <= 122: + seen[byte] = null + return seen.has_all(lowercase) diff --git a/exercises/practice/pangram/.meta/tests.toml b/exercises/practice/pangram/.meta/tests.toml new file mode 100644 index 0000000..10b5a33 --- /dev/null +++ b/exercises/practice/pangram/.meta/tests.toml @@ -0,0 +1,45 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[64f61791-508e-4f5c-83ab-05de042b0149] +description = "empty sentence" + +[74858f80-4a4d-478b-8a5e-c6477e4e4e84] +description = "perfect lower case" + +[61288860-35ca-4abe-ba08-f5df76ecbdcd] +description = "only lower case" + +[6564267d-8ac5-4d29-baf2-e7d2e304a743] +description = "missing the letter 'x'" + +[c79af1be-d715-4cdb-a5f2-b2fa3e7e0de0] +description = "missing the letter 'h'" + +[d835ec38-bc8f-48e4-9e36-eb232427b1df] +description = "with underscores" + +[8cc1e080-a178-4494-b4b3-06982c9be2a8] +description = "with numbers" + +[bed96b1c-ff95-45b8-9731-fdbdcb6ede9a] +description = "missing letters replaced by numbers" + +[938bd5d8-ade5-40e2-a2d9-55a338a01030] +description = "mixed case and punctuation" + +[2577bf54-83c8-402d-a64b-a2c0f7bb213a] +description = "case insensitive" +include = false + +[7138e389-83e4-4c6e-8413-1e40a0076951] +description = "a-m and A-M are 26 different characters but not a pangram" +reimplements = "2577bf54-83c8-402d-a64b-a2c0f7bb213a" diff --git a/exercises/practice/pangram/pangram.gd b/exercises/practice/pangram/pangram.gd new file mode 100644 index 0000000..0a17628 --- /dev/null +++ b/exercises/practice/pangram/pangram.gd @@ -0,0 +1,2 @@ +func is_pangram(sentence): + pass diff --git a/exercises/practice/pangram/pangram_test.gd b/exercises/practice/pangram/pangram_test.gd new file mode 100644 index 0000000..338b742 --- /dev/null +++ b/exercises/practice/pangram/pangram_test.gd @@ -0,0 +1,57 @@ +func test_empty_sentence(solution_script): + var input = "" + var expected = false + return [expected, solution_script.is_pangram(input)] + + +func test_perfect_lower_case(solution_script): + var input = "abcdefghijklmnopqrstuvwxyz" + var expected = true + return [expected, solution_script.is_pangram(input)] + + +func test_the_quick_brown_fox_jumps_over_the_lazy_dog(solution_script): + var input = "the quick brown fox jumps over the lazy dog" + var expected = true + return [expected, solution_script.is_pangram(input)] + + +func test_missing_the_letter_x(solution_script): + var input = "a quick movement of the enemy will jeopardize five gunboats" + var expected = false + return [expected, solution_script.is_pangram(input)] + + +func test_missing_the_letter_h(solution_script): + var input = "five boxing wizards jump quickly at it" + var expected = false + return [expected, solution_script.is_pangram(input)] + + +func test_with_underscores(solution_script): + var input = "the_quick_brown_fox_jumps_over_the_lazy_dog" + var expected = true + return [expected, solution_script.is_pangram(input)] + + +func test_with_numbers(solution_script): + var input = "the 1 quick brown fox jumps over the 2 lazy dogs" + var expected = true + return [expected, solution_script.is_pangram(input)] + +func test_missing_letters_replaced_by_numbers(solution_script): + var input = "7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog" + var expected = false + return [expected, solution_script.is_pangram(input)] + + +func test_mixed_case_and_punctuation(solution_script): + var input = "\"Five quacking Zephyrs jolt my wax bed.\"" + var expected = true + return [expected, solution_script.is_pangram(input)] + + +func test_case_insensitive(solution_script): + var input = "abcdefghijklm ABCDEFGHIJKLM" + var expected = false + return [expected, solution_script.is_pangram(input)] From 4cb47dc12576f91dba3bfb3b8867366ffdeb4b31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Wed, 27 Dec 2023 14:58:23 -0800 Subject: [PATCH 15/33] [New exercise]: triangle (#19) * Add triangle exercise * Fix merge markers --- .gdlintrc | 1 + config.json | 8 ++ .../practice/triangle/.docs/instructions.md | 29 ++++ exercises/practice/triangle/.meta/config.json | 19 +++ exercises/practice/triangle/.meta/example.gd | 23 +++ exercises/practice/triangle/.meta/tests.toml | 73 ++++++++++ exercises/practice/triangle/triangle.gd | 10 ++ exercises/practice/triangle/triangle_test.gd | 132 ++++++++++++++++++ 8 files changed, 295 insertions(+) create mode 100644 exercises/practice/triangle/.docs/instructions.md create mode 100644 exercises/practice/triangle/.meta/config.json create mode 100644 exercises/practice/triangle/.meta/example.gd create mode 100644 exercises/practice/triangle/.meta/tests.toml create mode 100644 exercises/practice/triangle/triangle.gd create mode 100644 exercises/practice/triangle/triangle_test.gd diff --git a/.gdlintrc b/.gdlintrc index 270cc85..3998c00 100644 --- a/.gdlintrc +++ b/.gdlintrc @@ -21,6 +21,7 @@ constant-name: _?[A-Z][A-Z0-9]*(_[A-Z0-9]+)* disable: [ unused-argument, max-line-length, + max-public-methods, ] duplicated-load: null enum-element-name: '[A-Z][A-Z0-9]*(_[A-Z0-9]+)*' diff --git a/config.json b/config.json index 6d1927b..06f8427 100644 --- a/config.json +++ b/config.json @@ -59,6 +59,14 @@ "prerequisites": [], "difficulty": 2 }, + { + "slug": "triangle", + "name": "triangle", + "uuid": "9762dd20-acef-4e3e-b304-8ae2a351d866", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "pangram", "name": "Pangram", diff --git a/exercises/practice/triangle/.docs/instructions.md b/exercises/practice/triangle/.docs/instructions.md new file mode 100644 index 0000000..ac39008 --- /dev/null +++ b/exercises/practice/triangle/.docs/instructions.md @@ -0,0 +1,29 @@ +# Instructions + +Determine if a triangle is equilateral, isosceles, or scalene. + +An _equilateral_ triangle has all three sides the same length. + +An _isosceles_ triangle has at least two sides the same length. +(It is sometimes specified as having exactly two sides the same length, but for the purposes of this exercise we'll say at least two.) + +A _scalene_ triangle has all sides of different lengths. + +## Note + +For a shape to be a triangle at all, all sides have to be of length > 0, and the sum of the lengths of any two sides must be greater than or equal to the length of the third side. + +In equations: + +Let `a`, `b`, and `c` be sides of the triangle. +Then all three of the following expressions must be true: + +```text +a + b ≥ c +b + c ≥ a +a + c ≥ b +``` + +See [Triangle Inequality][triangle-inequality] + +[triangle-inequality]: https://en.wikipedia.org/wiki/Triangle_inequality diff --git a/exercises/practice/triangle/.meta/config.json b/exercises/practice/triangle/.meta/config.json new file mode 100644 index 0000000..82672d4 --- /dev/null +++ b/exercises/practice/triangle/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "triangle.gd" + ], + "test": [ + "triangle_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Determine if a triangle is equilateral, isosceles, or scalene.", + "source": "The Ruby Koans triangle project, parts 1 & 2", + "source_url": "https://web.archive.org/web/20220831105330/http://rubykoans.com" +} diff --git a/exercises/practice/triangle/.meta/example.gd b/exercises/practice/triangle/.meta/example.gd new file mode 100644 index 0000000..1ab362b --- /dev/null +++ b/exercises/practice/triangle/.meta/example.gd @@ -0,0 +1,23 @@ +func is_valid(sides): + var all_sides_positive = sides.all(func(s): return s > 0) + sides.sort() + var satisfies_inequality = (sides[0] + sides[1]) >= sides[2] + return all_sides_positive and satisfies_inequality + + +func count_unique(lst): + return lst.reduce( + func(acc, elem): + acc[elem] = true + return acc, {}).size() + +func is_equilateral(sides): + return is_valid(sides) and count_unique(sides) == 1 + + +func is_isosceles(sides): + return is_valid(sides) and count_unique(sides) < 3 + + +func is_scalene(sides): + return is_valid(sides) and count_unique(sides) == 3 diff --git a/exercises/practice/triangle/.meta/tests.toml b/exercises/practice/triangle/.meta/tests.toml new file mode 100644 index 0000000..7db0916 --- /dev/null +++ b/exercises/practice/triangle/.meta/tests.toml @@ -0,0 +1,73 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[8b2c43ac-7257-43f9-b552-7631a91988af] +description = "equilateral triangle -> all sides are equal" + +[33eb6f87-0498-4ccf-9573-7f8c3ce92b7b] +description = "equilateral triangle -> any side is unequal" + +[c6585b7d-a8c0-4ad8-8a34-e21d36f7ad87] +description = "equilateral triangle -> no sides are equal" + +[16e8ceb0-eadb-46d1-b892-c50327479251] +description = "equilateral triangle -> all zero sides is not a triangle" + +[3022f537-b8e5-4cc1-8f12-fd775827a00c] +description = "equilateral triangle -> sides may be floats" + +[cbc612dc-d75a-4c1c-87fc-e2d5edd70b71] +description = "isosceles triangle -> last two sides are equal" + +[e388ce93-f25e-4daf-b977-4b7ede992217] +description = "isosceles triangle -> first two sides are equal" + +[d2080b79-4523-4c3f-9d42-2da6e81ab30f] +description = "isosceles triangle -> first and last sides are equal" + +[8d71e185-2bd7-4841-b7e1-71689a5491d8] +description = "isosceles triangle -> equilateral triangles are also isosceles" + +[840ed5f8-366f-43c5-ac69-8f05e6f10bbb] +description = "isosceles triangle -> no sides are equal" + +[2eba0cfb-6c65-4c40-8146-30b608905eae] +description = "isosceles triangle -> first triangle inequality violation" + +[278469cb-ac6b-41f0-81d4-66d9b828f8ac] +description = "isosceles triangle -> second triangle inequality violation" + +[90efb0c7-72bb-4514-b320-3a3892e278ff] +description = "isosceles triangle -> third triangle inequality violation" + +[adb4ee20-532f-43dc-8d31-e9271b7ef2bc] +description = "isosceles triangle -> sides may be floats" + +[e8b5f09c-ec2e-47c1-abec-f35095733afb] +description = "scalene triangle -> no sides are equal" + +[2510001f-b44d-4d18-9872-2303e7977dc1] +description = "scalene triangle -> all sides are equal" + +[c6e15a92-90d9-4fb3-90a2-eef64f8d3e1e] +description = "scalene triangle -> first and second sides are equal" + +[3da23a91-a166-419a-9abf-baf4868fd985] +description = "scalene triangle -> first and third sides are equal" + +[b6a75d98-1fef-4c42-8e9a-9db854ba0a4d] +description = "scalene triangle -> second and third sides are equal" + +[70ad5154-0033-48b7-af2c-b8d739cd9fdc] +description = "scalene triangle -> may not violate triangle inequality" + +[26d9d59d-f8f1-40d3-ad58-ae4d54123d7d] +description = "scalene triangle -> sides may be floats" diff --git a/exercises/practice/triangle/triangle.gd b/exercises/practice/triangle/triangle.gd new file mode 100644 index 0000000..9c2b6ac --- /dev/null +++ b/exercises/practice/triangle/triangle.gd @@ -0,0 +1,10 @@ +func is_equilateral(sides): + pass + + +func is_isosceles(sides): + pass + + +func is_scalene(sides): + pass diff --git a/exercises/practice/triangle/triangle_test.gd b/exercises/practice/triangle/triangle_test.gd new file mode 100644 index 0000000..64cb484 --- /dev/null +++ b/exercises/practice/triangle/triangle_test.gd @@ -0,0 +1,132 @@ +## Equilateral triangle tests + +func test_equilateral_all_sides_are_equal(solution_script): + var args = [2, 2, 2] + var expected = true + return [expected, solution_script.is_equilateral(args)] + + +func test_equilateral_any_side_is_unequal(solution_script): + var args = [2, 3, 2] + var expected = false + return [expected, solution_script.is_equilateral(args)] + + +func test_equilateral_no_sides_are_equal(solution_script): + var args = [5, 4, 6] + var expected = false + return [expected, solution_script.is_equilateral(args)] + + +func test_equilateral_all_zero_sides(solution_script): + var args = [0, 0, 0] + var expected = false + return [expected, solution_script.is_equilateral(args)] + + +func test_equilateral_sides_may_be_floats(solution_script): + var args = [0.5, 0.5, 0.5] + var expected = true + return [expected, solution_script.is_equilateral(args)] + + +## Isosceles triangle tests + + +func test_isosceles_last_two_equal(solution_script): + var args = [3, 4, 4] + var expected = true + return [expected, solution_script.is_isosceles(args)] + + +func test_isosceles_first_two_equal(solution_script): + var args = [4, 4, 3] + var expected = true + return [expected, solution_script.is_isosceles(args)] + + +func test_isosceles_first_and_last_equal(solution_script): + var args = [4, 3, 4] + var expected = true + return [expected, solution_script.is_isosceles(args)] + + +func test_isosceles_can_be_equilateral(solution_script): + var args = [4, 4, 4] + var expected = true + return [expected, solution_script.is_isosceles(args)] + + +func test_isosceles_no_sides_equal(solution_script): + var args = [2, 3, 4] + var expected = false + return [expected, solution_script.is_isosceles(args)] + + +func test_isosceles_first_inequality_violation(solution_script): + var args = [1, 1, 3] + var expected = false + return [expected, solution_script.is_isosceles(args)] + + +func test_isosceles_second_inequality_violation(solution_script): + var args = [1, 3, 1] + var expected = false + return [expected, solution_script.is_isosceles(args)] + + +func test_isosceles_third_inequality_violation(solution_script): + var args = [3, 1, 1] + var expected = false + return [expected, solution_script.is_isosceles(args)] + + +func test_isosceles_sides_may_be_floats(solution_script): + var args = [0.5, 0.4, 0.5] + var expected = true + return [expected, solution_script.is_isosceles(args)] + + +# Scalene triangle tests + + +func test_scalene_no_sides_equal(solution_script): + var args = [5, 4, 6] + var expected = true + return [expected, solution_script.is_scalene(args)] + + +func test_scalene_all_sides_equal(solution_script): + var args = [4, 4, 4] + var expected = false + return [expected, solution_script.is_scalene(args)] + + +func test_scalene_first_and_second_equal(solution_script): + var args = [4, 4, 3] + var expected = false + return [expected, solution_script.is_scalene(args)] + + +func test_scalene_first_and_third_equal(solution_script): + var args = [3, 4, 3] + var expected = false + return [expected, solution_script.is_scalene(args)] + + +func test_scalene_second_and_third_equal(solution_script): + var args = [4, 3, 3] + var expected = false + return [expected, solution_script.is_scalene(args)] + + +func test_scalene_inequality_violation(solution_script): + var args = [7, 3, 2] + var expected = false + return [expected, solution_script.is_scalene(args)] + + +func test_scalene_may_be_floats(solution_script): + var args = [0.5, 0.4, 0.6] + var expected = true + return [expected, solution_script.is_scalene(args)] From 09e701e2c6b509ff79587e31a3228fdd256a859a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:01:10 -0800 Subject: [PATCH 16/33] Add darts exercise (#30) --- config.json | 8 ++ .../practice/darts/.docs/instructions.md | 31 +++++++ exercises/practice/darts/.meta/config.json | 18 ++++ exercises/practice/darts/.meta/example.gd | 9 ++ exercises/practice/darts/.meta/tests.toml | 49 ++++++++++ exercises/practice/darts/darts.gd | 2 + exercises/practice/darts/darts_test.gd | 89 +++++++++++++++++++ 7 files changed, 206 insertions(+) create mode 100644 exercises/practice/darts/.docs/instructions.md create mode 100644 exercises/practice/darts/.meta/config.json create mode 100644 exercises/practice/darts/.meta/example.gd create mode 100644 exercises/practice/darts/.meta/tests.toml create mode 100644 exercises/practice/darts/darts.gd create mode 100644 exercises/practice/darts/darts_test.gd diff --git a/config.json b/config.json index 06f8427..0ff2780 100644 --- a/config.json +++ b/config.json @@ -74,6 +74,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "darts", + "name": "Darts", + "uuid": "0646b090-41a2-428d-b092-1ffbba71b316", + "practices": [], + "prerequisites": [], + "difficulty": 2 } ] }, diff --git a/exercises/practice/darts/.docs/instructions.md b/exercises/practice/darts/.docs/instructions.md new file mode 100644 index 0000000..5e57a86 --- /dev/null +++ b/exercises/practice/darts/.docs/instructions.md @@ -0,0 +1,31 @@ +# Instructions + +Write a function that returns the earned points in a single toss of a Darts game. + +[Darts][darts] is a game where players throw darts at a [target][darts-target]. + +In our particular instance of the game, the target rewards 4 different amounts of points, depending on where the dart lands: + +![Our dart scoreboard with values from a complete miss to a bullseye](https://assets.exercism.org/images/exercises/darts/darts-scoreboard.svg) + +- If the dart lands outside the target, player earns no points (0 points). +- If the dart lands in the outer circle of the target, player earns 1 point. +- If the dart lands in the middle circle of the target, player earns 5 points. +- If the dart lands in the inner circle of the target, player earns 10 points. + +The outer circle has a radius of 10 units (this is equivalent to the total radius for the entire target), the middle circle a radius of 5 units, and the inner circle a radius of 1. +Of course, they are all centered at the same point — that is, the circles are [concentric][] defined by the coordinates (0, 0). + +Write a function that given a point in the target (defined by its [Cartesian coordinates][cartesian-coordinates] `x` and `y`, where `x` and `y` are [real][real-numbers]), returns the correct amount earned by a dart landing at that point. + +## Credit + +The scoreboard image was created by [habere-et-dispertire][habere-et-dispertire] using [Inkscape][inkscape]. + +[darts]: https://en.wikipedia.org/wiki/Darts +[darts-target]: https://en.wikipedia.org/wiki/Darts#/media/File:Darts_in_a_dartboard.jpg +[concentric]: https://mathworld.wolfram.com/ConcentricCircles.html +[cartesian-coordinates]: https://www.mathsisfun.com/data/cartesian-coordinates.html +[real-numbers]: https://www.mathsisfun.com/numbers/real-numbers.html +[habere-et-dispertire]: https://exercism.org/profiles/habere-et-dispertire +[inkscape]: https://en.wikipedia.org/wiki/Inkscape diff --git a/exercises/practice/darts/.meta/config.json b/exercises/practice/darts/.meta/config.json new file mode 100644 index 0000000..c19b1de --- /dev/null +++ b/exercises/practice/darts/.meta/config.json @@ -0,0 +1,18 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "darts.gd" + ], + "test": [ + "darts_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Write a function that returns the earned points in a single toss of a Darts game.", + "source": "Inspired by an exercise created by a professor Della Paolera in Argentina" +} diff --git a/exercises/practice/darts/.meta/example.gd b/exercises/practice/darts/.meta/example.gd new file mode 100644 index 0000000..05bfeb0 --- /dev/null +++ b/exercises/practice/darts/.meta/example.gd @@ -0,0 +1,9 @@ +func score(x, y): + var distance = sqrt(pow(x, 2) + pow(y, 2)) + if distance <= 1: + return 10 + if distance <= 5: + return 5 + if distance <= 10: + return 1 + return 0 diff --git a/exercises/practice/darts/.meta/tests.toml b/exercises/practice/darts/.meta/tests.toml new file mode 100644 index 0000000..fbe2976 --- /dev/null +++ b/exercises/practice/darts/.meta/tests.toml @@ -0,0 +1,49 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[9033f731-0a3a-4d9c-b1c0-34a1c8362afb] +description = "Missed target" + +[4c9f6ff4-c489-45fd-be8a-1fcb08b4d0ba] +description = "On the outer circle" + +[14378687-ee58-4c9b-a323-b089d5274be8] +description = "On the middle circle" + +[849e2e63-85bd-4fed-bc3b-781ae962e2c9] +description = "On the inner circle" + +[1c5ffd9f-ea66-462f-9f06-a1303de5a226] +description = "Exactly on center" + +[b65abce3-a679-4550-8115-4b74bda06088] +description = "Near the center" + +[66c29c1d-44f5-40cf-9927-e09a1305b399] +description = "Just within the inner circle" + +[d1012f63-c97c-4394-b944-7beb3d0b141a] +description = "Just outside the inner circle" + +[ab2b5666-b0b4-49c3-9b27-205e790ed945] +description = "Just within the middle circle" + +[70f1424e-d690-4860-8caf-9740a52c0161] +description = "Just outside the middle circle" + +[a7dbf8db-419c-4712-8a7f-67602b69b293] +description = "Just within the outer circle" + +[e0f39315-9f9a-4546-96e4-a9475b885aa7] +description = "Just outside the outer circle" + +[045d7d18-d863-4229-818e-b50828c75d19] +description = "Asymmetric position between the inner and middle circles" diff --git a/exercises/practice/darts/darts.gd b/exercises/practice/darts/darts.gd new file mode 100644 index 0000000..9719675 --- /dev/null +++ b/exercises/practice/darts/darts.gd @@ -0,0 +1,2 @@ +func score(x, y): + pass diff --git a/exercises/practice/darts/darts_test.gd b/exercises/practice/darts/darts_test.gd new file mode 100644 index 0000000..39e9ba1 --- /dev/null +++ b/exercises/practice/darts/darts_test.gd @@ -0,0 +1,89 @@ +func test_missed_target(solution_script): + var x = -9 + var y = 9 + var expected = 0 + return [expected, solution_script.score(x, y)] + + +func test_on_the_outer_circle(solution_script): + var x = 0 + var y = 10 + var expected = 1 + return [expected, solution_script.score(x, y)] + + +func test_on_the_middle_circle(solution_script): + var x = -5 + var y = 0 + var expected = 5 + return [expected, solution_script.score(x, y)] + + +func test_on_the_inner_circle(solution_script): + var x = 0 + var y = -1 + var expected = 10 + return [expected, solution_script.score(x, y)] + + +func test_exactly_on_center(solution_script): + var x = 0 + var y = 0 + var expected = 10 + return [expected, solution_script.score(x, y)] + + +func test_near_the_center(solution_script): + var x = -0.1 + var y = -0.1 + var expected = 10 + return [expected, solution_script.score(x, y)] + + +func test_just_within_the_inner_circle(solution_script): + var x = 0.7 + var y = 0.7 + var expected = 10 + return [expected, solution_script.score(x, y)] + + +func test_just_outside_the_inner_circle(solution_script): + var x = 0.8 + var y = -0.8 + var expected = 5 + return [expected, solution_script.score(x, y)] + + +func test_just_within_the_middle_circle(solution_script): + var x = -3.5 + var y = 3.5 + var expected = 5 + return [expected, solution_script.score(x, y)] + + +func test_just_outside_the_middle_circle(solution_script): + var x = -3.6 + var y = -3.6 + var expected = 1 + return [expected, solution_script.score(x, y)] + + +func test_just_within_the_outer_circle(solution_script): + var x = -7.0 + var y = 7.0 + var expected = 1 + return [expected, solution_script.score(x, y)] + + +func test_just_outside_the_outer_circle(solution_script): + var x = 7.1 + var y = -7.1 + var expected = 0 + return [expected, solution_script.score(x, y)] + + +func test_asymmetric_position(solution_script): + var x = 0.5 + var y = -4 + var expected = 5 + return [expected, solution_script.score(x, y)] From 80601ea983ac8ec46648a6fedccd0746d626c37d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Thu, 28 Dec 2023 14:42:46 -0800 Subject: [PATCH 17/33] Add reverse-string (#31) * Add reverse-string * Remove gdlint CI --- .github/workflows/lint.yml | 20 ----------- config.json | 8 +++++ .../reverse-string/.docs/instructions.md | 7 ++++ .../practice/reverse-string/.meta/config.json | 19 +++++++++++ .../practice/reverse-string/.meta/example.gd | 5 +++ .../practice/reverse-string/.meta/tests.toml | 28 +++++++++++++++ .../practice/reverse-string/reverse_string.gd | 2 ++ .../reverse-string/reverse_string_test.gd | 34 +++++++++++++++++++ 8 files changed, 103 insertions(+), 20 deletions(-) delete mode 100644 .github/workflows/lint.yml create mode 100644 exercises/practice/reverse-string/.docs/instructions.md create mode 100644 exercises/practice/reverse-string/.meta/config.json create mode 100644 exercises/practice/reverse-string/.meta/example.gd create mode 100644 exercises/practice/reverse-string/.meta/tests.toml create mode 100644 exercises/practice/reverse-string/reverse_string.gd create mode 100644 exercises/practice/reverse-string/reverse_string_test.gd diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 9217f50..0000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: GDScript / Lint - -on: - push: - branches: [main] - pull_request: - workflow_dispatch: - -jobs: - lint: - runs-on: ubuntu-22.04 - steps: - - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - - name: Setup gdtoolkit - uses: Scony/godot-gdscript-toolkit@09af1747fd66629af601b1f14d1ac24203358686 - - - name: Lint - run: gdlint exercises diff --git a/config.json b/config.json index 0ff2780..29622b4 100644 --- a/config.json +++ b/config.json @@ -82,6 +82,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "reverse-string", + "name": "Reverse String", + "uuid": "963aeaed-a2d5-40e5-8f04-f17f404b5304", + "practices": [], + "prerequisites": [], + "difficulty": 2 } ] }, diff --git a/exercises/practice/reverse-string/.docs/instructions.md b/exercises/practice/reverse-string/.docs/instructions.md new file mode 100644 index 0000000..039ee33 --- /dev/null +++ b/exercises/practice/reverse-string/.docs/instructions.md @@ -0,0 +1,7 @@ +# Instructions + +Reverse a string + +For example: +input: "cool" +output: "looc" diff --git a/exercises/practice/reverse-string/.meta/config.json b/exercises/practice/reverse-string/.meta/config.json new file mode 100644 index 0000000..0aa6beb --- /dev/null +++ b/exercises/practice/reverse-string/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "reverse_string.gd" + ], + "test": [ + "reverse_string_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Reverse a string.", + "source": "Introductory challenge to reverse an input string", + "source_url": "https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb" +} diff --git a/exercises/practice/reverse-string/.meta/example.gd b/exercises/practice/reverse-string/.meta/example.gd new file mode 100644 index 0000000..1c56828 --- /dev/null +++ b/exercises/practice/reverse-string/.meta/example.gd @@ -0,0 +1,5 @@ +func reverse(str): + var result = "" + for i in range(str.length() - 1, -1, -1): + result += str[i] + return result diff --git a/exercises/practice/reverse-string/.meta/tests.toml b/exercises/practice/reverse-string/.meta/tests.toml new file mode 100644 index 0000000..0b04c4c --- /dev/null +++ b/exercises/practice/reverse-string/.meta/tests.toml @@ -0,0 +1,28 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[c3b7d806-dced-49ee-8543-933fd1719b1c] +description = "an empty string" + +[01ebf55b-bebb-414e-9dec-06f7bb0bee3c] +description = "a word" + +[0f7c07e4-efd1-4aaa-a07a-90b49ce0b746] +description = "a capitalized word" + +[71854b9c-f200-4469-9f5c-1e8e5eff5614] +description = "a sentence with punctuation" + +[1f8ed2f3-56f3-459b-8f3e-6d8d654a1f6c] +description = "a palindrome" + +[b9e7dec1-c6df-40bd-9fa3-cd7ded010c4c] +description = "an even-sized word" diff --git a/exercises/practice/reverse-string/reverse_string.gd b/exercises/practice/reverse-string/reverse_string.gd new file mode 100644 index 0000000..06ff5ac --- /dev/null +++ b/exercises/practice/reverse-string/reverse_string.gd @@ -0,0 +1,2 @@ +func reverse(str): + pass diff --git a/exercises/practice/reverse-string/reverse_string_test.gd b/exercises/practice/reverse-string/reverse_string_test.gd new file mode 100644 index 0000000..49f36e6 --- /dev/null +++ b/exercises/practice/reverse-string/reverse_string_test.gd @@ -0,0 +1,34 @@ +func test_empty_string(solution_script): + var str = "" + var expected = "" + return [expected, solution_script.reverse(str)] + + +func test_a_word(solution_script): + var str = "robot" + var expected = "tobor" + return [expected, solution_script.reverse(str)] + + +func test_a_capitalized_word(solution_script): + var str = "Ramen" + var expected = "nemaR" + return [expected, solution_script.reverse(str)] + + +func test_a_sentence_with_punctuation(solution_script): + var str = "I'm hungry!" + var expected = "!yrgnuh m'I" + return [expected, solution_script.reverse(str)] + + +func test_a_palindrome(solution_script): + var str = "racecar" + var expected = "racecar" + return [expected, solution_script.reverse(str)] + + +func test_an_even_sized_word(solution_script): + var str = "drawer" + var expected = "reward" + return [expected, solution_script.reverse(str)] From b3239e01b7ba1736127d6f798fa009bce538c7af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Thu, 28 Dec 2023 14:50:32 -0800 Subject: [PATCH 18/33] Update command for testing exercises (#25) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d692e87..164c8de 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Exercism exercises in GDScript. ## Testing -To test the exercises, run `./bin/test`. +To test the exercises, run `./bin/verify-exercises`. This command will iterate over all exercises and check to see if their exemplar/example implementation passes all the tests. ### Track linting From 1e6d251faaed49678780a8acab180e9e060f3407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=C2=A0Fertyk?= Date: Wed, 3 Jan 2024 20:19:53 +0100 Subject: [PATCH 19/33] Update Godot Engine typing (#33) --- config.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config.json b/config.json index 29622b4..af7e72d 100644 --- a/config.json +++ b/config.json @@ -97,8 +97,7 @@ "key_features": [], "tags": [ "paradigm/object_oriented", - "typing/static", - "typing/dynamic", + "typing/gradual", "execution_mode/interpreted", "platform/windows", "platform/mac", From ac3298a8855951fc4a9251247bf70c364e395c2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Wed, 3 Jan 2024 14:00:21 -0800 Subject: [PATCH 20/33] Add space-age exercise (#34) --- config.json | 8 +++ .../practice/space-age/.docs/instructions.md | 25 ++++++++++ .../practice/space-age/.meta/config.json | 19 +++++++ exercises/practice/space-age/.meta/example.gd | 18 +++++++ exercises/practice/space-age/.meta/tests.toml | 38 ++++++++++++++ exercises/practice/space-age/space_age.gd | 2 + .../practice/space-age/space_age_test.gd | 50 +++++++++++++++++++ 7 files changed, 160 insertions(+) create mode 100644 exercises/practice/space-age/.docs/instructions.md create mode 100644 exercises/practice/space-age/.meta/config.json create mode 100644 exercises/practice/space-age/.meta/example.gd create mode 100644 exercises/practice/space-age/.meta/tests.toml create mode 100644 exercises/practice/space-age/space_age.gd create mode 100644 exercises/practice/space-age/space_age_test.gd diff --git a/config.json b/config.json index af7e72d..95689ba 100644 --- a/config.json +++ b/config.json @@ -59,6 +59,14 @@ "prerequisites": [], "difficulty": 2 }, + { + "slug": "space-age", + "name": "Space Age", + "uuid": "6684cbd6-5a15-4e1b-a41c-7f9d17884e7a", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "triangle", "name": "triangle", diff --git a/exercises/practice/space-age/.docs/instructions.md b/exercises/practice/space-age/.docs/instructions.md new file mode 100644 index 0000000..fe938cc --- /dev/null +++ b/exercises/practice/space-age/.docs/instructions.md @@ -0,0 +1,25 @@ +# Instructions + +Given an age in seconds, calculate how old someone would be on: + +- Mercury: orbital period 0.2408467 Earth years +- Venus: orbital period 0.61519726 Earth years +- Earth: orbital period 1.0 Earth years, 365.25 Earth days, or 31557600 seconds +- Mars: orbital period 1.8808158 Earth years +- Jupiter: orbital period 11.862615 Earth years +- Saturn: orbital period 29.447498 Earth years +- Uranus: orbital period 84.016846 Earth years +- Neptune: orbital period 164.79132 Earth years + +So if you were told someone were 1,000,000,000 seconds old, you should +be able to say that they're 31.69 Earth-years old. + +If you're wondering why Pluto didn't make the cut, go watch [this YouTube video][pluto-video]. + +Note: The actual length of one complete orbit of the Earth around the sun is closer to 365.256 days (1 sidereal year). +The Gregorian calendar has, on average, 365.2425 days. +While not entirely accurate, 365.25 is the value used in this exercise. +See [Year on Wikipedia][year] for more ways to measure a year. + +[pluto-video]: https://www.youtube.com/watch?v=Z_2gbGXzFbs +[year]: https://en.wikipedia.org/wiki/Year#Summary diff --git a/exercises/practice/space-age/.meta/config.json b/exercises/practice/space-age/.meta/config.json new file mode 100644 index 0000000..2b51594 --- /dev/null +++ b/exercises/practice/space-age/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "space_age.gd" + ], + "test": [ + "space_age_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Given an age in seconds, calculate how old someone is in terms of a given planet's solar years.", + "source": "Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial.", + "source_url": "https://pine.fm/LearnToProgram/?Chapter=01" +} diff --git a/exercises/practice/space-age/.meta/example.gd b/exercises/practice/space-age/.meta/example.gd new file mode 100644 index 0000000..b2cf53b --- /dev/null +++ b/exercises/practice/space-age/.meta/example.gd @@ -0,0 +1,18 @@ +var EARTH_SECONDS = 31557600.0 + + +var orbital_periods = { + 'Mercury': 0.2408467, + 'Venus' : 0.61519726, + 'Earth' : 1, + 'Mars' : 1.8808158, + 'Jupiter' : 11.862615, + 'Saturn' : 29.447498, + 'Uranus' : 84.016846, + 'Neptune' : 164.79132 +} + + +func on_planet(planet, seconds): + var ratio = orbital_periods.get(planet) + return seconds / EARTH_SECONDS / ratio diff --git a/exercises/practice/space-age/.meta/tests.toml b/exercises/practice/space-age/.meta/tests.toml new file mode 100644 index 0000000..a62017e --- /dev/null +++ b/exercises/practice/space-age/.meta/tests.toml @@ -0,0 +1,38 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[84f609af-5a91-4d68-90a3-9e32d8a5cd34] +description = "age on Earth" + +[ca20c4e9-6054-458c-9312-79679ffab40b] +description = "age on Mercury" + +[502c6529-fd1b-41d3-8fab-65e03082b024] +description = "age on Venus" + +[9ceadf5e-a0d5-4388-9d40-2c459227ceb8] +description = "age on Mars" + +[42927dc3-fe5e-4f76-a5b5-f737fc19bcde] +description = "age on Jupiter" + +[8469b332-7837-4ada-b27c-00ee043ebcad] +description = "age on Saturn" + +[999354c1-76f8-4bb5-a672-f317b6436743] +description = "age on Uranus" + +[80096d30-a0d4-4449-903e-a381178355d8] +description = "age on Neptune" + +[57b96e2a-1178-40b7-b34d-f3c9c34e4bf4] +description = "invalid planet causes error" +include = false diff --git a/exercises/practice/space-age/space_age.gd b/exercises/practice/space-age/space_age.gd new file mode 100644 index 0000000..9d10315 --- /dev/null +++ b/exercises/practice/space-age/space_age.gd @@ -0,0 +1,2 @@ +func on_planet(planet, seconds): + pass diff --git a/exercises/practice/space-age/space_age_test.gd b/exercises/practice/space-age/space_age_test.gd new file mode 100644 index 0000000..cfc2645 --- /dev/null +++ b/exercises/practice/space-age/space_age_test.gd @@ -0,0 +1,50 @@ +func roughly_equal(n1, n2): + return abs(n1 - n2) <= 0.01 + + +func test_age_on_Earth(solution_script): + var age = solution_script.on_planet('Earth', 1000000000) + var expected = 31.69 + return [true, roughly_equal(age, expected)] + + +func test_age_on_Mercury(solution_script): + var age = solution_script.on_planet('Mercury', 2134835688) + var expected = 280.88 + return [true, roughly_equal(age, expected)] + + +func test_age_on_Venus(solution_script): + var age = solution_script.on_planet('Venus', 189839836) + var expected = 9.78 + return [true, roughly_equal(age, expected)] + + +func test_age_on_Mars(solution_script): + var age = solution_script.on_planet('Mars', 2129871239) + var expected = 35.88 + return [true, roughly_equal(age, expected)] + + +func test_age_on_Jupiter(solution_script): + var age = solution_script.on_planet('Jupiter', 901876382) + var expected = 2.41 + return [true, roughly_equal(age, expected)] + + +func test_age_on_Saturn(solution_script): + var age = solution_script.on_planet('Saturn', 2000000000) + var expected = 2.15 + return [true, roughly_equal(age, expected)] + + +func test_age_on_Uranus(solution_script): + var age = solution_script.on_planet('Uranus', 1210123456) + var expected = 0.46 + return [true, roughly_equal(age, expected)] + + +func test_age_on_Neptune(solution_script): + var age = solution_script.on_planet('Neptune', 1821023456) + var expected = 0.35 + return [true, roughly_equal(age, expected)] From e681502b983fa23ad35c2df6bca8f7ba025d45ec Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Tue, 16 Jan 2024 21:56:05 +0100 Subject: [PATCH 21/33] leap: sync (#35) * Sync the `leap` exercise's docs with the latest data. * Sync the `leap` exercise's metadata with the latest data. --- exercises/practice/leap/.docs/instructions.md | 21 +------------------ exercises/practice/leap/.docs/introduction.md | 16 ++++++++++++++ exercises/practice/leap/.meta/config.json | 2 +- 3 files changed, 18 insertions(+), 21 deletions(-) create mode 100644 exercises/practice/leap/.docs/introduction.md diff --git a/exercises/practice/leap/.docs/instructions.md b/exercises/practice/leap/.docs/instructions.md index a83826b..b14f856 100644 --- a/exercises/practice/leap/.docs/instructions.md +++ b/exercises/practice/leap/.docs/instructions.md @@ -1,22 +1,3 @@ # Instructions -Given a year, report if it is a leap year. - -The tricky thing here is that a leap year in the Gregorian calendar occurs: - -```text -on every year that is evenly divisible by 4 - except every year that is evenly divisible by 100 - unless the year is also evenly divisible by 400 -``` - -For example, 1997 is not a leap year, but 1996 is. -1900 is not a leap year, but 2000 is. - -## Notes - -Though our exercise adopts some very simple rules, there is more to learn! - -For a delightful, four minute explanation of the whole leap year phenomenon, go watch [this youtube video][video]. - -[video]: https://www.youtube.com/watch?v=xX96xng7sAE +Your task is to determine whether a given year is a leap year. diff --git a/exercises/practice/leap/.docs/introduction.md b/exercises/practice/leap/.docs/introduction.md new file mode 100644 index 0000000..4ffd2da --- /dev/null +++ b/exercises/practice/leap/.docs/introduction.md @@ -0,0 +1,16 @@ +# Introduction + +A leap year (in the Gregorian calendar) occurs: + +- In every year that is evenly divisible by 4. +- 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. + +Some examples: + +- 1997 was not a leap year as it's not divisible by 4. +- 1900 was not a leap year as it's not divisible by 400. +- 2000 was a leap year! + +~~~~exercism/note +For a delightful, four-minute explanation of the whole phenomenon of leap years, check out [this YouTube video](https://www.youtube.com/watch?v=xX96xng7sAE). +~~~~ diff --git a/exercises/practice/leap/.meta/config.json b/exercises/practice/leap/.meta/config.json index a07a6f1..2ba21ea 100644 --- a/exercises/practice/leap/.meta/config.json +++ b/exercises/practice/leap/.meta/config.json @@ -13,7 +13,7 @@ ".meta/example.gd" ] }, - "blurb": "Given a year, report if it is a leap year.", + "blurb": "Determine whether a given year is a leap year.", "source": "CodeRanch Cattle Drive, Assignment 3", "source_url": "https://coderanch.com/t/718816/Leap" } From 45fa165303cd81fd4ce91077871bfaa02b1605ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=C2=A0Fertyk?= Date: Wed, 17 Jan 2024 19:25:13 +0100 Subject: [PATCH 22/33] Add isogram exercise (#36) --- config.json | 8 +++ .../practice/isogram/.docs/instructions.md | 14 +++++ exercises/practice/isogram/.meta/config.json | 19 +++++++ exercises/practice/isogram/.meta/example.gd | 8 +++ exercises/practice/isogram/.meta/tests.toml | 52 ++++++++++++++++++ exercises/practice/isogram/isogram.gd | 2 + exercises/practice/isogram/isogram_test.gd | 54 +++++++++++++++++++ 7 files changed, 157 insertions(+) create mode 100644 exercises/practice/isogram/.docs/instructions.md create mode 100644 exercises/practice/isogram/.meta/config.json create mode 100644 exercises/practice/isogram/.meta/example.gd create mode 100644 exercises/practice/isogram/.meta/tests.toml create mode 100644 exercises/practice/isogram/isogram.gd create mode 100644 exercises/practice/isogram/isogram_test.gd diff --git a/config.json b/config.json index 95689ba..c17680b 100644 --- a/config.json +++ b/config.json @@ -98,6 +98,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "isogram", + "name": "Isogram", + "uuid": "fe577db6-0ebe-4c6a-9eb7-04407c7eb900", + "practices": [], + "prerequisites": [], + "difficulty": 2 } ] }, diff --git a/exercises/practice/isogram/.docs/instructions.md b/exercises/practice/isogram/.docs/instructions.md new file mode 100644 index 0000000..2e8df85 --- /dev/null +++ b/exercises/practice/isogram/.docs/instructions.md @@ -0,0 +1,14 @@ +# Instructions + +Determine if a word or phrase is an isogram. + +An 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. + +Examples of isograms: + +- lumberjacks +- background +- downstream +- six-year-old + +The word _isograms_, however, is not an isogram, because the s repeats. diff --git a/exercises/practice/isogram/.meta/config.json b/exercises/practice/isogram/.meta/config.json new file mode 100644 index 0000000..4b7c1bc --- /dev/null +++ b/exercises/practice/isogram/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "pfertyk" + ], + "files": { + "solution": [ + "isogram.gd" + ], + "test": [ + "isogram_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Determine if a word or phrase is an isogram.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Isogram" +} diff --git a/exercises/practice/isogram/.meta/example.gd b/exercises/practice/isogram/.meta/example.gd new file mode 100644 index 0000000..fb1bd84 --- /dev/null +++ b/exercises/practice/isogram/.meta/example.gd @@ -0,0 +1,8 @@ +func is_isogram(string: String): + string = string.to_lower().replace("-", "").replace(" ", "") + var letters = {} + + for c in string: + letters[c] = true + + return letters.size() == string.length() diff --git a/exercises/practice/isogram/.meta/tests.toml b/exercises/practice/isogram/.meta/tests.toml new file mode 100644 index 0000000..ba04c66 --- /dev/null +++ b/exercises/practice/isogram/.meta/tests.toml @@ -0,0 +1,52 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[a0e97d2d-669e-47c7-8134-518a1e2c4555] +description = "empty string" + +[9a001b50-f194-4143-bc29-2af5ec1ef652] +description = "isogram with only lower case characters" + +[8ddb0ca3-276e-4f8b-89da-d95d5bae78a4] +description = "word with one duplicated character" + +[6450b333-cbc2-4b24-a723-0b459b34fe18] +description = "word with one duplicated character from the end of the alphabet" + +[a15ff557-dd04-4764-99e7-02cc1a385863] +description = "longest reported english isogram" + +[f1a7f6c7-a42f-4915-91d7-35b2ea11c92e] +description = "word with duplicated character in mixed case" + +[14a4f3c1-3b47-4695-b645-53d328298942] +description = "word with duplicated character in mixed case, lowercase first" + +[423b850c-7090-4a8a-b057-97f1cadd7c42] +description = "hypothetical isogrammic word with hyphen" + +[93dbeaa0-3c5a-45c2-8b25-428b8eacd4f2] +description = "hypothetical word with duplicated character following hyphen" + +[36b30e5c-173f-49c6-a515-93a3e825553f] +description = "isogram with duplicated hyphen" + +[cdabafa0-c9f4-4c1f-b142-689c6ee17d93] +description = "made-up name that is an isogram" + +[5fc61048-d74e-48fd-bc34-abfc21552d4d] +description = "duplicated character in the middle" + +[310ac53d-8932-47bc-bbb4-b2b94f25a83e] +description = "same first and last characters" + +[0d0b8644-0a1e-4a31-a432-2b3ee270d847] +description = "word with duplicated character and with two hyphens" diff --git a/exercises/practice/isogram/isogram.gd b/exercises/practice/isogram/isogram.gd new file mode 100644 index 0000000..1a20227 --- /dev/null +++ b/exercises/practice/isogram/isogram.gd @@ -0,0 +1,2 @@ +func is_isogram(string: String): + pass diff --git a/exercises/practice/isogram/isogram_test.gd b/exercises/practice/isogram/isogram_test.gd new file mode 100644 index 0000000..544152b --- /dev/null +++ b/exercises/practice/isogram/isogram_test.gd @@ -0,0 +1,54 @@ +func test_empty_string(solution_script): + return [solution_script.is_isogram(""), true] + + +func test_isogram_with_only_lower_case_characters(solution_script): + return [solution_script.is_isogram("isogram"), true] + + +func test_word_with_one_duplicated_character(solution_script): + return [solution_script.is_isogram("eleven"), false] + + +func test_word_with_one_duplicated_character_from_the_end_of_the_alphabet(solution_script): + return [solution_script.is_isogram("zzyzx"), false] + + +func test_longest_reported_english_isogram(solution_script): + return [solution_script.is_isogram("subdermatoglyphic"), true] + + +func test_word_with_duplicated_character_in_mixed_case(solution_script): + return [solution_script.is_isogram("Alphabet"), false] + + +func test_word_with_duplicated_character_in_mixed_case_lowercase_first(solution_script): + return [solution_script.is_isogram("alphAbet"), false] + + +func test_hypothetical_isogrammic_word_with_hyphen(solution_script): + return [solution_script.is_isogram("thumbscrew-japingly"), true] + + +func test_hypothetical_word_with_duplicated_character_following_hyphen(solution_script): + return [solution_script.is_isogram("thumbscrew-jappingly"), false] + + +func test_isogram_with_duplicated_hyphen(solution_script): + return [solution_script.is_isogram("six-year-old"), true] + + +func test_made_up_name_that_is_an_isogram(solution_script): + return [solution_script.is_isogram("Emily Jung Schwartzkopf"), true] + + +func test_duplicated_character_in_the_middle(solution_script): + return [solution_script.is_isogram("accentor"), false] + + +func test_same_first_and_last_characters(solution_script): + return [solution_script.is_isogram("angola"), false] + + +func test_word_with_duplicated_character_and_with_two_hyphens(solution_script): + return [solution_script.is_isogram("up-to-date"), false] From 1217bedc4e3095864d0ef555f36c03351c37496a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=C2=A0Fertyk?= Date: Mon, 22 Jan 2024 18:31:32 +0100 Subject: [PATCH 23/33] Add raindrops exercise (#37) --- config.json | 8 +++ .../practice/raindrops/.docs/instructions.md | 20 ++++++ .../practice/raindrops/.meta/config.json | 19 +++++ exercises/practice/raindrops/.meta/example.gd | 13 ++++ exercises/practice/raindrops/.meta/tests.toml | 64 +++++++++++++++++ exercises/practice/raindrops/raindrops.gd | 2 + .../practice/raindrops/raindrops_test.gd | 70 +++++++++++++++++++ 7 files changed, 196 insertions(+) create mode 100644 exercises/practice/raindrops/.docs/instructions.md create mode 100644 exercises/practice/raindrops/.meta/config.json create mode 100644 exercises/practice/raindrops/.meta/example.gd create mode 100644 exercises/practice/raindrops/.meta/tests.toml create mode 100644 exercises/practice/raindrops/raindrops.gd create mode 100644 exercises/practice/raindrops/raindrops_test.gd diff --git a/config.json b/config.json index c17680b..2786f9c 100644 --- a/config.json +++ b/config.json @@ -106,6 +106,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "raindrops", + "name": "Raindrops", + "uuid": "b176d30a-4e4b-4d12-9331-67b03112b575", + "practices": [], + "prerequisites": [], + "difficulty": 2 } ] }, diff --git a/exercises/practice/raindrops/.docs/instructions.md b/exercises/practice/raindrops/.docs/instructions.md new file mode 100644 index 0000000..fc61d36 --- /dev/null +++ b/exercises/practice/raindrops/.docs/instructions.md @@ -0,0 +1,20 @@ +# Instructions + +Your task is to convert a number into a string that contains raindrop sounds corresponding to certain potential factors. +A factor is a number that evenly divides into another number, leaving no remainder. +The simplest way to test if one number is a factor of another is to use the [modulo operation][modulo]. + +The rules of `raindrops` are that if a given number: + +- has 3 as a factor, add 'Pling' to the result. +- has 5 as a factor, add 'Plang' to the result. +- has 7 as a factor, add 'Plong' to the result. +- _does not_ have any of 3, 5, or 7 as a factor, the result should be the digits of the number. + +## Examples + +- 28 has 7 as a factor, but not 3 or 5, so the result would be "Plong". +- 30 has both 3 and 5 as factors, but not 7, so the result would be "PlingPlang". +- 34 is not factored by 3, 5, or 7, so the result would be "34". + +[modulo]: https://en.wikipedia.org/wiki/Modulo_operation diff --git a/exercises/practice/raindrops/.meta/config.json b/exercises/practice/raindrops/.meta/config.json new file mode 100644 index 0000000..1935f42 --- /dev/null +++ b/exercises/practice/raindrops/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "pfertyk" + ], + "files": { + "solution": [ + "raindrops.gd" + ], + "test": [ + "raindrops_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Convert a number to a string, the content of which depends on the number's factors.", + "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.", + "source_url": "https://en.wikipedia.org/wiki/Fizz_buzz" +} diff --git a/exercises/practice/raindrops/.meta/example.gd b/exercises/practice/raindrops/.meta/example.gd new file mode 100644 index 0000000..c0b5cd3 --- /dev/null +++ b/exercises/practice/raindrops/.meta/example.gd @@ -0,0 +1,13 @@ +func convert(number: int): + var sounds = "" + if number % 3 == 0: + sounds += "Pling" + if number % 5 == 0: + sounds += "Plang" + if number % 7 == 0: + sounds += "Plong" + + if not sounds: + sounds = str(number) + + return sounds diff --git a/exercises/practice/raindrops/.meta/tests.toml b/exercises/practice/raindrops/.meta/tests.toml new file mode 100644 index 0000000..756d16c --- /dev/null +++ b/exercises/practice/raindrops/.meta/tests.toml @@ -0,0 +1,64 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[1575d549-e502-46d4-a8e1-6b7bec6123d8] +description = "the sound for 1 is 1" + +[1f51a9f9-4895-4539-b182-d7b0a5ab2913] +description = "the sound for 3 is Pling" + +[2d9bfae5-2b21-4bcd-9629-c8c0e388f3e0] +description = "the sound for 5 is Plang" + +[d7e60daa-32ef-4c23-b688-2abff46c4806] +description = "the sound for 7 is Plong" + +[6bb4947b-a724-430c-923f-f0dc3d62e56a] +description = "the sound for 6 is Pling as it has a factor 3" + +[ce51e0e8-d9d4-446d-9949-96eac4458c2d] +description = "2 to the power 3 does not make a raindrop sound as 3 is the exponent not the base" + +[0dd66175-e3e2-47fc-8750-d01739856671] +description = "the sound for 9 is Pling as it has a factor 3" + +[022c44d3-2182-4471-95d7-c575af225c96] +description = "the sound for 10 is Plang as it has a factor 5" + +[37ab74db-fed3-40ff-b7b9-04acdfea8edf] +description = "the sound for 14 is Plong as it has a factor of 7" + +[31f92999-6afb-40ee-9aa4-6d15e3334d0f] +description = "the sound for 15 is PlingPlang as it has factors 3 and 5" + +[ff9bb95d-6361-4602-be2c-653fe5239b54] +description = "the sound for 21 is PlingPlong as it has factors 3 and 7" + +[d2e75317-b72e-40ab-8a64-6734a21dece1] +description = "the sound for 25 is Plang as it has a factor 5" + +[a09c4c58-c662-4e32-97fe-f1501ef7125c] +description = "the sound for 27 is Pling as it has a factor 3" + +[bdf061de-8564-4899-a843-14b48b722789] +description = "the sound for 35 is PlangPlong as it has factors 5 and 7" + +[c4680bee-69ba-439d-99b5-70c5fd1a7a83] +description = "the sound for 49 is Plong as it has a factor 7" + +[17f2bc9a-b65a-4d23-8ccd-266e8c271444] +description = "the sound for 52 is 52" + +[e46677ed-ff1a-419f-a740-5c713d2830e4] +description = "the sound for 105 is PlingPlangPlong as it has factors 3, 5 and 7" + +[13c6837a-0fcd-4b86-a0eb-20572f7deb0b] +description = "the sound for 3125 is Plang as it has a factor 5" diff --git a/exercises/practice/raindrops/raindrops.gd b/exercises/practice/raindrops/raindrops.gd new file mode 100644 index 0000000..63e2e39 --- /dev/null +++ b/exercises/practice/raindrops/raindrops.gd @@ -0,0 +1,2 @@ +func convert(number: int): + pass diff --git a/exercises/practice/raindrops/raindrops_test.gd b/exercises/practice/raindrops/raindrops_test.gd new file mode 100644 index 0000000..6fe8506 --- /dev/null +++ b/exercises/practice/raindrops/raindrops_test.gd @@ -0,0 +1,70 @@ +func test_the_sound_for_1_is_1(solution_script): + return [solution_script.convert(1), "1"] + + +func test_the_sound_for_3_is_pling(solution_script): + return [solution_script.convert(3), "Pling"] + + +func test_the_sound_for_5_is_plang(solution_script): + return [solution_script.convert(5), "Plang"] + + +func test_the_sound_for_7_is_plong(solution_script): + return [solution_script.convert(7), "Plong"] + + +func test_the_sound_for_6_is_pling_as_it_has_a_factor_3(solution_script): + return [solution_script.convert(6), "Pling"] + + +func test_2_to_the_power_3_does_not_make_a_raindrop_sound_as_3_is_the_exponent_not_the_base(solution_script): + return [solution_script.convert(8), "8"] + + +func test_the_sound_for_9_is_pling_as_it_has_a_factor_3(solution_script): + return [solution_script.convert(9), "Pling"] + + +func test_the_sound_for_10_is_plang_as_it_has_a_factor_5(solution_script): + return [solution_script.convert(10), "Plang"] + + +func test_the_sound_for_14_is_plong_as_it_has_a_factor_of_7(solution_script): + return [solution_script.convert(14), "Plong"] + + +func test_the_sound_for_15_is_pling_plang_as_it_has_factors_3_and_5(solution_script): + return [solution_script.convert(15), "PlingPlang"] + + +func test_the_sound_for_21_is_pling_plong_as_it_has_factors_3_and_7(solution_script): + return [solution_script.convert(21), "PlingPlong"] + + +func test_the_sound_for_25_is_plang_as_it_has_a_factor_5(solution_script): + return [solution_script.convert(25), "Plang"] + + +func test_the_sound_for_27_is_pling_as_it_has_a_factor_3(solution_script): + return [solution_script.convert(27), "Pling"] + + +func test_the_sound_for_35_is_plang_plong_as_it_has_factors_5_and_7(solution_script): + return [solution_script.convert(35), "PlangPlong"] + + +func test_the_sound_for_49_is_plong_as_it_has_a_factor_7(solution_script): + return [solution_script.convert(49), "Plong"] + + +func test_the_sound_for_52_is_52(solution_script): + return [solution_script.convert(52), "52"] + + +func test_the_sound_for_105_is_pling_plang_plong_as_it_has_factors_3_5_and_7(solution_script): + return [solution_script.convert(105), "PlingPlangPlong"] + + +func test_the_sound_for_3125_is_plang_as_it_has_a_factor_5(solution_script): + return [solution_script.convert(3125), "Plang"] From 6dca036bd4091c00eb6416f758e0efaeb4500a6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=C2=A0Fertyk?= Date: Mon, 22 Jan 2024 20:31:53 +0100 Subject: [PATCH 24/33] Add flatten-array exercise (#39) --- config.json | 8 +++ .../flatten-array/.docs/instructions.md | 11 ++++ .../practice/flatten-array/.meta/config.json | 19 ++++++ .../practice/flatten-array/.meta/example.gd | 8 +++ .../practice/flatten-array/.meta/tests.toml | 43 +++++++++++++ .../practice/flatten-array/flatten_array.gd | 2 + .../flatten-array/flatten_array_test.gd | 64 +++++++++++++++++++ 7 files changed, 155 insertions(+) create mode 100644 exercises/practice/flatten-array/.docs/instructions.md create mode 100644 exercises/practice/flatten-array/.meta/config.json create mode 100644 exercises/practice/flatten-array/.meta/example.gd create mode 100644 exercises/practice/flatten-array/.meta/tests.toml create mode 100644 exercises/practice/flatten-array/flatten_array.gd create mode 100644 exercises/practice/flatten-array/flatten_array_test.gd diff --git a/config.json b/config.json index 2786f9c..a40f441 100644 --- a/config.json +++ b/config.json @@ -114,6 +114,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "flatten-array", + "name": "Flatten Array", + "uuid": "a9dd0e93-f34a-47dd-87d2-2e689f5f93f2", + "practices": [], + "prerequisites": [], + "difficulty": 2 } ] }, diff --git a/exercises/practice/flatten-array/.docs/instructions.md b/exercises/practice/flatten-array/.docs/instructions.md new file mode 100644 index 0000000..51bea67 --- /dev/null +++ b/exercises/practice/flatten-array/.docs/instructions.md @@ -0,0 +1,11 @@ +# Instructions + +Take a nested list and return a single flattened list with all values except nil/null. + +The challenge is to write a function that accepts an arbitrarily-deep nested list-like structure and returns a flattened structure without any nil/null values. + +For example: + +input: [1,[2,3,null,4],[null],5] + +output: [1,2,3,4,5] diff --git a/exercises/practice/flatten-array/.meta/config.json b/exercises/practice/flatten-array/.meta/config.json new file mode 100644 index 0000000..6d1695c --- /dev/null +++ b/exercises/practice/flatten-array/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "pfertyk" + ], + "files": { + "solution": [ + "flatten_array.gd" + ], + "test": [ + "flatten_array_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Take a nested list and return a single list with all values except nil/null.", + "source": "Interview Question", + "source_url": "https://reference.wolfram.com/language/ref/Flatten.html" +} diff --git a/exercises/practice/flatten-array/.meta/example.gd b/exercises/practice/flatten-array/.meta/example.gd new file mode 100644 index 0000000..04c5643 --- /dev/null +++ b/exercises/practice/flatten-array/.meta/example.gd @@ -0,0 +1,8 @@ +func flatten(iterable): + var flatted = [] + for item in iterable: + if is_instance_of(item, TYPE_ARRAY): + flatted.append_array(flatten(item)) + elif item != null: + flatted.append(item) + return flatted diff --git a/exercises/practice/flatten-array/.meta/tests.toml b/exercises/practice/flatten-array/.meta/tests.toml new file mode 100644 index 0000000..6300219 --- /dev/null +++ b/exercises/practice/flatten-array/.meta/tests.toml @@ -0,0 +1,43 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[8c71dabd-da60-422d-a290-4a571471fb14] +description = "empty" + +[d268b919-963c-442d-9f07-82b93f1b518c] +description = "no nesting" + +[3f15bede-c856-479e-bb71-1684b20c6a30] +description = "flattens a nested array" + +[c84440cc-bb3a-48a6-862c-94cf23f2815d] +description = "flattens array with just integers present" + +[d3d99d39-6be5-44f5-a31d-6037d92ba34f] +description = "5 level nesting" + +[d572bdba-c127-43ed-bdcd-6222ac83d9f7] +description = "6 level nesting" + +[0705a8e5-dc86-4cec-8909-150c5e54fa9c] +description = "null values are omitted from the final result" + +[c6cf26de-8ccd-4410-84bd-b9efd88fd2bc] +description = "consecutive null values at the front of the list are omitted from the final result" + +[382c5242-587e-4577-b8ce-a5fb51e385a1] +description = "consecutive null values in the middle of the list are omitted from the final result" + +[ef1d4790-1b1e-4939-a179-51ace0829dbd] +description = "6 level nest list with null values" + +[85721643-705a-4150-93ab-7ae398e2942d] +description = "all values in nested list are null" diff --git a/exercises/practice/flatten-array/flatten_array.gd b/exercises/practice/flatten-array/flatten_array.gd new file mode 100644 index 0000000..40f0687 --- /dev/null +++ b/exercises/practice/flatten-array/flatten_array.gd @@ -0,0 +1,2 @@ +func flatten(iterable): + pass diff --git a/exercises/practice/flatten-array/flatten_array_test.gd b/exercises/practice/flatten-array/flatten_array_test.gd new file mode 100644 index 0000000..7949fed --- /dev/null +++ b/exercises/practice/flatten-array/flatten_array_test.gd @@ -0,0 +1,64 @@ +func test_empty(solution_script): + var inputs = [] + var expected = [] + return [solution_script.flatten(inputs), expected] + + +func test_no_nesting(solution_script): + var inputs = [0, 1, 2] + var expected = [0, 1, 2] + return [solution_script.flatten(inputs), expected] + + +func test_flattens_a_nested_array(solution_script): + var inputs = [[[]]] + var expected = [] + return [solution_script.flatten(inputs), expected] + + +func test_flattens_array_with_just_integers_present(solution_script): + var inputs = [1, [2, 3, 4, 5, 6, 7], 8] + var expected = [1, 2, 3, 4, 5, 6, 7, 8] + return [solution_script.flatten(inputs), expected] + + +func test_5_level_nesting(solution_script): + var inputs = [0, 2, [[2, 3], 8, 100, 4, [[[50]]]], -2] + var expected = [0, 2, 2, 3, 8, 100, 4, 50, -2] + return [solution_script.flatten(inputs), expected] + + +func test_6_level_nesting(solution_script): + var inputs = [1, [2, [[3]], [4, [[5]]], 6, 7], 8] + var expected = [1, 2, 3, 4, 5, 6, 7, 8] + return [solution_script.flatten(inputs), expected] + + +func test_null_values_are_omitted_from_the_final_result(solution_script): + var inputs = [1, 2, null] + var expected = [1, 2] + return [solution_script.flatten(inputs), expected] + + +func test_consecutive_null_values_at_the_front_of_the_list_are_omitted_from_the_final_result(solution_script): + var inputs = [null, null, 3] + var expected = [3] + return [solution_script.flatten(inputs), expected] + + +func test_consecutive_null_values_in_the_middle_of_the_list_are_omitted_from_the_final_result(solution_script): + var inputs = [1, null, null, 4] + var expected = [1, 4] + return [solution_script.flatten(inputs), expected] + + +func test_6_level_nest_list_with_null_values(solution_script): + var inputs = [0, 2, [[2, 3], 8, [[100]], null, [[null]]], -2] + var expected = [0, 2, 2, 3, 8, 100, -2] + return [solution_script.flatten(inputs), expected] + + +func test_all_values_in_nested_list_are_null(solution_script): + var inputs = [null, [[[null]]], null, null, [[null, null], null], null] + var expected = [] + return [solution_script.flatten(inputs), expected] From b7d6434116bf768961031d6c95393fd0ae53d5a6 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 25 Jan 2024 13:58:58 +0100 Subject: [PATCH 25/33] Sync fetch-configlet.ps1 script (#42) --- bin/fetch-configlet.ps1 | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/bin/fetch-configlet.ps1 b/bin/fetch-configlet.ps1 index ab8f103..a7896b2 100644 --- a/bin/fetch-configlet.ps1 +++ b/bin/fetch-configlet.ps1 @@ -12,20 +12,31 @@ $requestOpts = @{ RetryIntervalSec = 1 } -$arch = If ([Environment]::Is64BitOperatingSystem) { "x86-64" } Else { "i386" } -$fileName = "configlet_.+_windows_$arch.zip" - Function Get-DownloadUrl { + $arch = If ([Environment]::Is64BitOperatingSystem) { "x86-64" } Else { "i386" } $latestUrl = "https://api.github.com/repos/exercism/configlet/releases/latest" - Invoke-RestMethod -Uri $latestUrl -PreserveAuthorizationOnRedirect @requestOpts - | Select-Object -ExpandProperty assets - | Where-Object { $_.browser_download_url -match $FileName } - | Select-Object -ExpandProperty browser_download_url + Invoke-RestMethod -Uri $latestUrl -PreserveAuthorizationOnRedirect @requestOpts ` + | Select-Object -ExpandProperty assets ` + | Where-Object { $_.name -match "^configlet_.+_windows_${arch}.zip$" } ` + | Select-Object -ExpandProperty browser_download_url -First 1 } -$downloadUrl = Get-DownloadUrl $outputDirectory = "bin" -$outputFile = Join-Path -Path $outputDirectory -ChildPath $fileName -Invoke-WebRequest -Uri $downloadUrl -OutFile $outputFile @requestOpts -Expand-Archive $outputFile -DestinationPath $outputDirectory -Force -Remove-Item -Path $outputFile +if (!(Test-Path -Path $outputDirectory)) { + Write-Output "Error: no ./bin directory found. This script should be ran from a repo root." + exit 1 +} + +Write-Output "Fetching configlet..." +$downloadUrl = Get-DownloadUrl +$outputFileName = "configlet.zip" +$outputPath = Join-Path -Path $outputDirectory -ChildPath $outputFileName +Invoke-WebRequest -Uri $downloadUrl -OutFile $outputPath @requestOpts + +$configletPath = Join-Path -Path $outputDirectory -ChildPath "configlet.exe" +if (Test-Path -Path $configletPath) { Remove-Item -Path $configletPath } +[System.IO.Compression.ZipFile]::ExtractToDirectory($outputPath, $outputDirectory) +Remove-Item -Path $outputPath + +$configletVersion = (Select-String -Pattern "/releases/download/(.+?)/" -InputObject $downloadUrl -AllMatches).Matches.Groups[1].Value +Write-Output "Downloaded configlet ${configletVersion} to ${configletPath}" From 57d6b332a742e888a6bb5e842029264b962d6f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=C2=A0Fertyk?= Date: Tue, 30 Jan 2024 17:54:50 +0100 Subject: [PATCH 26/33] Add luhn exercise (#40) --- config.json | 8 ++ .../practice/flatten-array/flatten_array.gd | 2 +- exercises/practice/luhn/.docs/instructions.md | 64 ++++++++++ exercises/practice/luhn/.meta/config.json | 19 +++ exercises/practice/luhn/.meta/example.gd | 22 ++++ exercises/practice/luhn/.meta/tests.toml | 76 ++++++++++++ exercises/practice/luhn/luhn.gd | 5 + exercises/practice/luhn/luhn_test.gd | 117 ++++++++++++++++++ 8 files changed, 312 insertions(+), 1 deletion(-) create mode 100644 exercises/practice/luhn/.docs/instructions.md create mode 100644 exercises/practice/luhn/.meta/config.json create mode 100644 exercises/practice/luhn/.meta/example.gd create mode 100644 exercises/practice/luhn/.meta/tests.toml create mode 100644 exercises/practice/luhn/luhn.gd create mode 100644 exercises/practice/luhn/luhn_test.gd diff --git a/config.json b/config.json index a40f441..5c0bfee 100644 --- a/config.json +++ b/config.json @@ -122,6 +122,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "luhn", + "name": "Luhn", + "uuid": "8f7a50ef-60fc-4e72-99de-c5dcf6ae2577", + "practices": [], + "prerequisites": [], + "difficulty": 3 } ] }, diff --git a/exercises/practice/flatten-array/flatten_array.gd b/exercises/practice/flatten-array/flatten_array.gd index 40f0687..58ef34d 100644 --- a/exercises/practice/flatten-array/flatten_array.gd +++ b/exercises/practice/flatten-array/flatten_array.gd @@ -1,2 +1,2 @@ func flatten(iterable): - pass + pass diff --git a/exercises/practice/luhn/.docs/instructions.md b/exercises/practice/luhn/.docs/instructions.md new file mode 100644 index 0000000..8cbe791 --- /dev/null +++ b/exercises/practice/luhn/.docs/instructions.md @@ -0,0 +1,64 @@ +# Instructions + +Given a number determine whether or not it is valid per the Luhn formula. + +The [Luhn algorithm][luhn] is a simple checksum formula used to validate a variety of identification numbers, such as credit card numbers and Canadian Social Insurance Numbers. + +The task is to check if a given string is valid. + +## Validating a Number + +Strings of length 1 or less are not valid. +Spaces are allowed in the input, but they should be stripped before checking. +All other non-digit characters are disallowed. + +### Example 1: valid credit card number + +```text +4539 3195 0343 6467 +``` + +The first step of the Luhn algorithm is to double every second digit, starting from the right. +We will be doubling + +```text +4_3_ 3_9_ 0_4_ 6_6_ +``` + +If doubling the number results in a number greater than 9 then subtract 9 from the product. +The results of our doubling: + +```text +8569 6195 0383 3437 +``` + +Then sum all of the digits: + +```text +8+5+6+9+6+1+9+5+0+3+8+3+3+4+3+7 = 80 +``` + +If the sum is evenly divisible by 10, then the number is valid. +This number is valid! + +### Example 2: invalid credit card number + +```text +8273 1232 7352 0569 +``` + +Double the second digits, starting from the right + +```text +7253 2262 5312 0539 +``` + +Sum the digits + +```text +7+2+5+3+2+2+6+2+5+3+1+2+0+5+3+9 = 57 +``` + +57 is not evenly divisible by 10, so this number is not valid. + +[luhn]: https://en.wikipedia.org/wiki/Luhn_algorithm diff --git a/exercises/practice/luhn/.meta/config.json b/exercises/practice/luhn/.meta/config.json new file mode 100644 index 0000000..54db742 --- /dev/null +++ b/exercises/practice/luhn/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "pfertyk" + ], + "files": { + "solution": [ + "luhn.gd" + ], + "test": [ + "luhn_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Given a number determine whether or not it is valid per the Luhn formula.", + "source": "The Luhn Algorithm on Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Luhn_algorithm" +} diff --git a/exercises/practice/luhn/.meta/example.gd b/exercises/practice/luhn/.meta/example.gd new file mode 100644 index 0000000..0c56dda --- /dev/null +++ b/exercises/practice/luhn/.meta/example.gd @@ -0,0 +1,22 @@ +@export var card_num : String + + +func valid(): + var num = card_num.replace(" ", "") + if len(num) <= 1: + return false + + var checksum = 0 + for index in range(len(num)): + var char = num[len(num) - 1 - index] + if not char.is_valid_int(): + return false + if index % 2 == 1: + var digit = int(char) + digit *= 2 + if digit > 9: + digit -= 9 + checksum += digit + else: + checksum += int(char) + return checksum % 10 == 0 diff --git a/exercises/practice/luhn/.meta/tests.toml b/exercises/practice/luhn/.meta/tests.toml new file mode 100644 index 0000000..c0be0c4 --- /dev/null +++ b/exercises/practice/luhn/.meta/tests.toml @@ -0,0 +1,76 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[792a7082-feb7-48c7-b88b-bbfec160865e] +description = "single digit strings can not be valid" + +[698a7924-64d4-4d89-8daa-32e1aadc271e] +description = "a single zero is invalid" + +[73c2f62b-9b10-4c9f-9a04-83cee7367965] +description = "a simple valid SIN that remains valid if reversed" + +[9369092e-b095-439f-948d-498bd076be11] +description = "a simple valid SIN that becomes invalid if reversed" + +[8f9f2350-1faf-4008-ba84-85cbb93ffeca] +description = "a valid Canadian SIN" + +[1cdcf269-6560-44fc-91f6-5819a7548737] +description = "invalid Canadian SIN" + +[656c48c1-34e8-4e60-9a5a-aad8a367810a] +description = "invalid credit card" + +[20e67fad-2121-43ed-99a8-14b5b856adb9] +description = "invalid long number with an even remainder" + +[7e7c9fc1-d994-457c-811e-d390d52fba5e] +description = "invalid long number with a remainder divisible by 5" + +[ad2a0c5f-84ed-4e5b-95da-6011d6f4f0aa] +description = "valid number with an even number of digits" + +[ef081c06-a41f-4761-8492-385e13c8202d] +description = "valid number with an odd number of spaces" + +[bef66f64-6100-4cbb-8f94-4c9713c5e5b2] +description = "valid strings with a non-digit added at the end become invalid" + +[2177e225-9ce7-40f6-b55d-fa420e62938e] +description = "valid strings with punctuation included become invalid" + +[ebf04f27-9698-45e1-9afe-7e0851d0fe8d] +description = "valid strings with symbols included become invalid" + +[08195c5e-ce7f-422c-a5eb-3e45fece68ba] +description = "single zero with space is invalid" + +[12e63a3c-f866-4a79-8c14-b359fc386091] +description = "more than a single zero is valid" + +[ab56fa80-5de8-4735-8a4a-14dae588663e] +description = "input digit 9 is correctly converted to output digit 9" + +[b9887ee8-8337-46c5-bc45-3bcab51bc36f] +description = "very long input is valid" + +[8a7c0e24-85ea-4154-9cf1-c2db90eabc08] +description = "valid luhn with an odd number of digits and non zero first digit" + +[39a06a5a-5bad-4e0f-b215-b042d46209b1] +description = "using ascii value for non-doubled non-digit isn't allowed" + +[f94cf191-a62f-4868-bc72-7253114aa157] +description = "using ascii value for doubled non-digit isn't allowed" + +[8b72ad26-c8be-49a2-b99c-bcc3bf631b33] +description = "non-numeric, non-space char in the middle with a sum that's divisible by 10 isn't allowed" diff --git a/exercises/practice/luhn/luhn.gd b/exercises/practice/luhn/luhn.gd new file mode 100644 index 0000000..24724f5 --- /dev/null +++ b/exercises/practice/luhn/luhn.gd @@ -0,0 +1,5 @@ +@export var card_num : String + + +func valid(): + pass diff --git a/exercises/practice/luhn/luhn_test.gd b/exercises/practice/luhn/luhn_test.gd new file mode 100644 index 0000000..304e335 --- /dev/null +++ b/exercises/practice/luhn/luhn_test.gd @@ -0,0 +1,117 @@ +func test_single_digit_strings_can_not_be_valid(solution_script): + solution_script.card_num = "1" + return [solution_script.valid(), false] + + +func test_a_single_zero_is_invalid(solution_script): + solution_script.card_num = "0" + return [solution_script.valid(), false] + + +func test_a_simple_valid_sin_that_remains_valid_if_reversed(solution_script): + solution_script.card_num = "059" + return [solution_script.valid(), true] + + +func test_a_simple_valid_sin_that_becomes_invalid_if_reversed(solution_script): + solution_script.card_num = "59" + return [solution_script.valid(), true] + + +func test_a_valid_canadian_sin(solution_script): + solution_script.card_num = "055 444 285" + return [solution_script.valid(), true] + + +func test_invalid_canadian_sin(solution_script): + solution_script.card_num = "055 444 286" + return [solution_script.valid(), false] + + +func test_invalid_credit_card(solution_script): + solution_script.card_num = "8273 1232 7352 0569" + return [solution_script.valid(), false] + + +func test_invalid_long_number_with_an_even_remainder(solution_script): + solution_script.card_num = "1 2345 6789 1234 5678 9012" + return [solution_script.valid(), false] + + +func test_invalid_long_number_with_a_remainder_divisible_by_5(solution_script): + solution_script.card_num = "1 2345 6789 1234 5678 9013" + return [solution_script.valid(), false] + + +func test_valid_number_with_an_even_number_of_digits(solution_script): + solution_script.card_num = "095 245 88" + return [solution_script.valid(), true] + + +func test_valid_number_with_an_odd_number_of_spaces(solution_script): + solution_script.card_num = "234 567 891 234" + return [solution_script.valid(), true] + + +func test_valid_strings_with_a_non_digit_added_at_the_end_become_invalid(solution_script): + solution_script.card_num = "059a" + return [solution_script.valid(), false] + + +func test_valid_strings_with_punctuation_included_become_invalid(solution_script): + solution_script.card_num = "055-444-285" + return [solution_script.valid(), false] + + +func test_valid_strings_with_symbols_included_become_invalid(solution_script): + solution_script.card_num = "055# 444$ 285" + return [solution_script.valid(), false] + + +func test_single_zero_with_space_is_invalid(solution_script): + solution_script.card_num = " 0" + return [solution_script.valid(), false] + + +func test_more_than_a_single_zero_is_valid(solution_script): + solution_script.card_num = "0000 0" + return [solution_script.valid(), true] + + +func test_input_digit_9_is_correctly_converted_to_output_digit_9(solution_script): + solution_script.card_num = "091" + return [solution_script.valid(), true] + + +func test_very_long_input_is_valid(solution_script): + solution_script.card_num = "9999999999 9999999999 9999999999 9999999999" + return [solution_script.valid(), true] + + +func test_valid_luhn_with_an_odd_number_of_digits_and_non_zero_first_digit(solution_script): + solution_script.card_num = "109" + return [solution_script.valid(), true] + + +func test_using_ascii_value_for_non_doubled_non_digit_isn_t_allowed(solution_script): + solution_script.card_num = "055b 444 285" + return [solution_script.valid(), false] + + +func test_using_ascii_value_for_doubled_non_digit_isn_t_allowed(solution_script): + solution_script.card_num = ":9" + return [solution_script.valid(), false] + + +func test_non_numeric_non_space_char_in_the_middle_with_a_sum_that_s_divisible_by_10_isn_t_allowed(solution_script): + solution_script.card_num = "59%59" + return [solution_script.valid(), false] + + +func test_is_valid_can_be_called_repeatedly(solution_script): + # This test was added, because we saw many implementations + # in which the first call to valid() worked, but the + # second call failed. + solution_script.card_num = "055 444 285" + return [solution_script.valid(), true] + return [solution_script.valid(), true] From b3a66f0ed17441f210868938f6594b8ade78e780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=C2=A0Fertyk?= Date: Wed, 31 Jan 2024 19:20:36 +0100 Subject: [PATCH 27/33] Add pop-count exercise (#41) --- config.json | 8 ++++ .../practice/pop-count/.docs/instructions.md | 8 ++++ .../practice/pop-count/.docs/introduction.md | 47 +++++++++++++++++++ .../practice/pop-count/.meta/config.json | 19 ++++++++ exercises/practice/pop-count/.meta/example.gd | 2 + exercises/practice/pop-count/.meta/tests.toml | 22 +++++++++ exercises/practice/pop-count/pop_count.gd | 2 + .../practice/pop-count/pop_count_test.gd | 14 ++++++ 8 files changed, 122 insertions(+) create mode 100644 exercises/practice/pop-count/.docs/instructions.md create mode 100644 exercises/practice/pop-count/.docs/introduction.md create mode 100644 exercises/practice/pop-count/.meta/config.json create mode 100644 exercises/practice/pop-count/.meta/example.gd create mode 100644 exercises/practice/pop-count/.meta/tests.toml create mode 100644 exercises/practice/pop-count/pop_count.gd create mode 100644 exercises/practice/pop-count/pop_count_test.gd diff --git a/config.json b/config.json index 5c0bfee..8f20c81 100644 --- a/config.json +++ b/config.json @@ -130,6 +130,14 @@ "practices": [], "prerequisites": [], "difficulty": 3 + }, + { + "slug": "pop-count", + "name": "Eliud's Eggs", + "uuid": "3a40dd65-7b56-4e0f-aed6-0e0a28753ca9", + "practices": [], + "prerequisites": [], + "difficulty": 3 } ] }, diff --git a/exercises/practice/pop-count/.docs/instructions.md b/exercises/practice/pop-count/.docs/instructions.md new file mode 100644 index 0000000..b0c2df5 --- /dev/null +++ b/exercises/practice/pop-count/.docs/instructions.md @@ -0,0 +1,8 @@ +# Instructions + +Your task is to count the number of 1 bits in the binary representation of a number. + +## Restrictions + +Keep your hands off that bit-count functionality provided by your standard library! +Solve this one yourself using other basic tools instead. diff --git a/exercises/practice/pop-count/.docs/introduction.md b/exercises/practice/pop-count/.docs/introduction.md new file mode 100644 index 0000000..49eaffd --- /dev/null +++ b/exercises/practice/pop-count/.docs/introduction.md @@ -0,0 +1,47 @@ +# Introduction + +Your friend Eliud inherited a farm from her grandma Tigist. +Her granny was an inventor and had a tendency to build things in an overly complicated manner. +The chicken coop has a digital display showing an encoded number representing the positions of all eggs that could be picked up. + +Eliud is asking you to write a program that shows the actual number of eggs in the coop. + +The position information encoding is calculated as follows: + +1. Scan the potential egg-laying spots and mark down a `1` for an existing egg or a `0` for an empty spot. +2. Convert the number from binary to decimal. +3. Show the result on the display. + +Example 1: + +```text +Chicken Coop: + _ _ _ _ _ _ _ +|E| |E|E| | |E| + +Resulting Binary: + 1 0 1 1 0 0 1 + +Decimal number on the display: +89 + +Actual eggs in the coop: +4 +``` + +Example 2: + +```text +Chicken Coop: + _ _ _ _ _ _ _ _ +| | | |E| | | | | + +Resulting Binary: + 0 0 0 1 0 0 0 0 + +Decimal number on the display: +16 + +Actual eggs in the coop: +1 +``` diff --git a/exercises/practice/pop-count/.meta/config.json b/exercises/practice/pop-count/.meta/config.json new file mode 100644 index 0000000..5c7743f --- /dev/null +++ b/exercises/practice/pop-count/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "pfertyk" + ], + "files": { + "solution": [ + "pop_count.gd" + ], + "test": [ + "pop_count_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Help Eliud count the number of eggs in her chicken coop by counting the number of 1 bits in a binary representation.", + "source": "Christian Willner, Eric Willigers", + "source_url": "https://forum.exercism.org/t/new-exercise-suggestion-pop-count/7632/5" +} diff --git a/exercises/practice/pop-count/.meta/example.gd b/exercises/practice/pop-count/.meta/example.gd new file mode 100644 index 0000000..21d3bc9 --- /dev/null +++ b/exercises/practice/pop-count/.meta/example.gd @@ -0,0 +1,2 @@ +func egg_count(display_value): + return String.num_int64(display_value, 2).count("1") diff --git a/exercises/practice/pop-count/.meta/tests.toml b/exercises/practice/pop-count/.meta/tests.toml new file mode 100644 index 0000000..e11683c --- /dev/null +++ b/exercises/practice/pop-count/.meta/tests.toml @@ -0,0 +1,22 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[559e789d-07d1-4422-9004-3b699f83bca3] +description = "0 eggs" + +[97223282-f71e-490c-92f0-b3ec9e275aba] +description = "1 egg" + +[1f8fd18f-26e9-4144-9a0e-57cdfc4f4ff5] +description = "4 eggs" + +[0c18be92-a498-4ef2-bcbb-28ac4b06cb81] +description = "13 eggs" diff --git a/exercises/practice/pop-count/pop_count.gd b/exercises/practice/pop-count/pop_count.gd new file mode 100644 index 0000000..b10b6e4 --- /dev/null +++ b/exercises/practice/pop-count/pop_count.gd @@ -0,0 +1,2 @@ +func egg_count(display_value): + pass diff --git a/exercises/practice/pop-count/pop_count_test.gd b/exercises/practice/pop-count/pop_count_test.gd new file mode 100644 index 0000000..0810742 --- /dev/null +++ b/exercises/practice/pop-count/pop_count_test.gd @@ -0,0 +1,14 @@ +func test_0_eggs(solution_script): + return [solution_script.egg_count(0), 0] + + +func test_1_egg(solution_script): + return [solution_script.egg_count(16), 1] + + +func test_4_eggs(solution_script): + return [solution_script.egg_count(89), 4] + + +func test_13_eggs(solution_script): + return [solution_script.egg_count(2000000000), 13] From 7fddc3124038facd9bf33bd2fa8138af3a9160d0 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Mon, 5 Feb 2024 18:37:28 +0100 Subject: [PATCH 28/33] `pop-count`: rename to `eliuds-eggs` (#47) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Rename the `pop-count` exercise to `eliuds-eggs`. * Rename remaining pop-count references --------- Co-authored-by: Paweł Fertyk --- config.json | 2 +- .../practice/{pop-count => eliuds-eggs}/.docs/instructions.md | 0 .../practice/{pop-count => eliuds-eggs}/.docs/introduction.md | 0 .../practice/{pop-count => eliuds-eggs}/.meta/config.json | 4 ++-- .../practice/{pop-count => eliuds-eggs}/.meta/example.gd | 0 .../practice/{pop-count => eliuds-eggs}/.meta/tests.toml | 0 .../{pop-count/pop_count.gd => eliuds-eggs/eliuds_eggs.gd} | 0 .../pop_count_test.gd => eliuds-eggs/eliuds_eggs_test.gd} | 0 8 files changed, 3 insertions(+), 3 deletions(-) rename exercises/practice/{pop-count => eliuds-eggs}/.docs/instructions.md (100%) rename exercises/practice/{pop-count => eliuds-eggs}/.docs/introduction.md (100%) rename exercises/practice/{pop-count => eliuds-eggs}/.meta/config.json (89%) rename exercises/practice/{pop-count => eliuds-eggs}/.meta/example.gd (100%) rename exercises/practice/{pop-count => eliuds-eggs}/.meta/tests.toml (100%) rename exercises/practice/{pop-count/pop_count.gd => eliuds-eggs/eliuds_eggs.gd} (100%) rename exercises/practice/{pop-count/pop_count_test.gd => eliuds-eggs/eliuds_eggs_test.gd} (100%) diff --git a/config.json b/config.json index 8f20c81..fcac80b 100644 --- a/config.json +++ b/config.json @@ -132,7 +132,7 @@ "difficulty": 3 }, { - "slug": "pop-count", + "slug": "eliuds-eggs", "name": "Eliud's Eggs", "uuid": "3a40dd65-7b56-4e0f-aed6-0e0a28753ca9", "practices": [], diff --git a/exercises/practice/pop-count/.docs/instructions.md b/exercises/practice/eliuds-eggs/.docs/instructions.md similarity index 100% rename from exercises/practice/pop-count/.docs/instructions.md rename to exercises/practice/eliuds-eggs/.docs/instructions.md diff --git a/exercises/practice/pop-count/.docs/introduction.md b/exercises/practice/eliuds-eggs/.docs/introduction.md similarity index 100% rename from exercises/practice/pop-count/.docs/introduction.md rename to exercises/practice/eliuds-eggs/.docs/introduction.md diff --git a/exercises/practice/pop-count/.meta/config.json b/exercises/practice/eliuds-eggs/.meta/config.json similarity index 89% rename from exercises/practice/pop-count/.meta/config.json rename to exercises/practice/eliuds-eggs/.meta/config.json index 5c7743f..a39de7f 100644 --- a/exercises/practice/pop-count/.meta/config.json +++ b/exercises/practice/eliuds-eggs/.meta/config.json @@ -4,10 +4,10 @@ ], "files": { "solution": [ - "pop_count.gd" + "eliuds_eggs.gd" ], "test": [ - "pop_count_test.gd" + "eliuds_eggs_test.gd" ], "example": [ ".meta/example.gd" diff --git a/exercises/practice/pop-count/.meta/example.gd b/exercises/practice/eliuds-eggs/.meta/example.gd similarity index 100% rename from exercises/practice/pop-count/.meta/example.gd rename to exercises/practice/eliuds-eggs/.meta/example.gd diff --git a/exercises/practice/pop-count/.meta/tests.toml b/exercises/practice/eliuds-eggs/.meta/tests.toml similarity index 100% rename from exercises/practice/pop-count/.meta/tests.toml rename to exercises/practice/eliuds-eggs/.meta/tests.toml diff --git a/exercises/practice/pop-count/pop_count.gd b/exercises/practice/eliuds-eggs/eliuds_eggs.gd similarity index 100% rename from exercises/practice/pop-count/pop_count.gd rename to exercises/practice/eliuds-eggs/eliuds_eggs.gd diff --git a/exercises/practice/pop-count/pop_count_test.gd b/exercises/practice/eliuds-eggs/eliuds_eggs_test.gd similarity index 100% rename from exercises/practice/pop-count/pop_count_test.gd rename to exercises/practice/eliuds-eggs/eliuds_eggs_test.gd From cec83bb82b22de93f57c82bb16ef1767726a18b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=C2=A0Fertyk?= Date: Tue, 6 Feb 2024 17:58:11 +0100 Subject: [PATCH 29/33] Add atbash-cipher exercise (#45) --- config.json | 8 +++ .../atbash-cipher/.docs/instructions.md | 27 ++++++++ .../practice/atbash-cipher/.meta/config.json | 19 ++++++ .../practice/atbash-cipher/.meta/example.gd | 32 +++++++++ .../practice/atbash-cipher/.meta/tests.toml | 52 ++++++++++++++ .../practice/atbash-cipher/atbash_cipher.gd | 6 ++ .../atbash-cipher/atbash_cipher_test.gd | 67 +++++++++++++++++++ 7 files changed, 211 insertions(+) create mode 100644 exercises/practice/atbash-cipher/.docs/instructions.md create mode 100644 exercises/practice/atbash-cipher/.meta/config.json create mode 100644 exercises/practice/atbash-cipher/.meta/example.gd create mode 100644 exercises/practice/atbash-cipher/.meta/tests.toml create mode 100644 exercises/practice/atbash-cipher/atbash_cipher.gd create mode 100644 exercises/practice/atbash-cipher/atbash_cipher_test.gd diff --git a/config.json b/config.json index fcac80b..cdd15ed 100644 --- a/config.json +++ b/config.json @@ -123,6 +123,14 @@ "prerequisites": [], "difficulty": 2 }, + { + "uuid": "9a52fffc-2672-41fb-b3ea-bef9c801726d", + "slug": "atbash-cipher", + "name": "Atbash Cipher", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "luhn", "name": "Luhn", diff --git a/exercises/practice/atbash-cipher/.docs/instructions.md b/exercises/practice/atbash-cipher/.docs/instructions.md new file mode 100644 index 0000000..21ca2ce --- /dev/null +++ b/exercises/practice/atbash-cipher/.docs/instructions.md @@ -0,0 +1,27 @@ +# Instructions + +Create an implementation of the atbash cipher, an ancient encryption system created in the Middle East. + +The Atbash cipher is a simple substitution cipher that relies on transposing all the letters in the alphabet such that the resulting alphabet is backwards. +The first letter is replaced with the last letter, the second with the second-last, and so on. + +An Atbash cipher for the Latin alphabet would be as follows: + +```text +Plain: abcdefghijklmnopqrstuvwxyz +Cipher: zyxwvutsrqponmlkjihgfedcba +``` + +It is a very weak cipher because it only has one possible key, and it is a simple mono-alphabetic substitution cipher. +However, this may not have been an issue in the cipher's time. + +Ciphertext is written out in groups of fixed length, the traditional group size being 5 letters, leaving numbers unchanged, and punctuation is excluded. +This is to make it harder to guess things based on word boundaries. +All text will be encoded as lowercase letters. + +## Examples + +- Encoding `test` gives `gvhg` +- Encoding `x123 yes` gives `c123b vh` +- Decoding `gvhg` gives `test` +- Decoding `gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt` gives `thequickbrownfoxjumpsoverthelazydog` diff --git a/exercises/practice/atbash-cipher/.meta/config.json b/exercises/practice/atbash-cipher/.meta/config.json new file mode 100644 index 0000000..db4dddd --- /dev/null +++ b/exercises/practice/atbash-cipher/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "pfertyk" + ], + "files": { + "solution": [ + "atbash_cipher.gd" + ], + "test": [ + "atbash_cipher_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Create an implementation of the atbash cipher, an ancient encryption system created in the Middle East.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Atbash" +} diff --git a/exercises/practice/atbash-cipher/.meta/example.gd b/exercises/practice/atbash-cipher/.meta/example.gd new file mode 100644 index 0000000..9a2b7bd --- /dev/null +++ b/exercises/practice/atbash-cipher/.meta/example.gd @@ -0,0 +1,32 @@ +const BLOCK_SIZE = 5 + + +func to_int(char): + return char.unicode_at(0) + + +func translate(str): + var result = "" + + for char in str.to_lower(): + if char.is_valid_int(): + result += char + elif char.is_valid_identifier() and not char == "_": + var new_char = String.chr(to_int("z") + to_int("a") - to_int(char)) + result += new_char + + return result + + +func encode(plain_text): + var ciphered_text = translate(plain_text) + var chunks = [] + + for i in range(0, len(ciphered_text), BLOCK_SIZE): + chunks.append(ciphered_text.substr(i, BLOCK_SIZE)) + + return " ".join(chunks) + + +func decode(ciphered_text): + return translate(ciphered_text) diff --git a/exercises/practice/atbash-cipher/.meta/tests.toml b/exercises/practice/atbash-cipher/.meta/tests.toml new file mode 100644 index 0000000..c082d07 --- /dev/null +++ b/exercises/practice/atbash-cipher/.meta/tests.toml @@ -0,0 +1,52 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[2f47ebe1-eab9-4d6b-b3c6-627562a31c77] +description = "encode -> encode yes" + +[b4ffe781-ea81-4b74-b268-cc58ba21c739] +description = "encode -> encode no" + +[10e48927-24ab-4c4d-9d3f-3067724ace00] +description = "encode -> encode OMG" + +[d59b8bc3-509a-4a9a-834c-6f501b98750b] +description = "encode -> encode spaces" + +[31d44b11-81b7-4a94-8b43-4af6a2449429] +description = "encode -> encode mindblowingly" + +[d503361a-1433-48c0-aae0-d41b5baa33ff] +description = "encode -> encode numbers" + +[79c8a2d5-0772-42d4-b41b-531d0b5da926] +description = "encode -> encode deep thought" + +[9ca13d23-d32a-4967-a1fd-6100b8742bab] +description = "encode -> encode all the letters" + +[bb50e087-7fdf-48e7-9223-284fe7e69851] +description = "decode -> decode exercism" + +[ac021097-cd5d-4717-8907-b0814b9e292c] +description = "decode -> decode a sentence" + +[18729de3-de74-49b8-b68c-025eaf77f851] +description = "decode -> decode numbers" + +[0f30325f-f53b-415d-ad3e-a7a4f63de034] +description = "decode -> decode all the letters" + +[39640287-30c6-4c8c-9bac-9d613d1a5674] +description = "decode -> decode with too many spaces" + +[b34edf13-34c0-49b5-aa21-0768928000d5] +description = "decode -> decode with no spaces" diff --git a/exercises/practice/atbash-cipher/atbash_cipher.gd b/exercises/practice/atbash-cipher/atbash_cipher.gd new file mode 100644 index 0000000..598db79 --- /dev/null +++ b/exercises/practice/atbash-cipher/atbash_cipher.gd @@ -0,0 +1,6 @@ +func encode(plain_text): + pass + + +func decode(ciphered_text): + pass diff --git a/exercises/practice/atbash-cipher/atbash_cipher_test.gd b/exercises/practice/atbash-cipher/atbash_cipher_test.gd new file mode 100644 index 0000000..efa2ccd --- /dev/null +++ b/exercises/practice/atbash-cipher/atbash_cipher_test.gd @@ -0,0 +1,67 @@ +func test_encode_yes(solution_script): + return [solution_script.encode("yes"), "bvh"] + + +func test_encode_no(solution_script): + return [solution_script.encode("no"), "ml"] + + +func test_encode_omg(solution_script): + return [solution_script.encode("OMG"), "lnt"] + + +func test_encode_spaces(solution_script): + return [solution_script.encode("O M G"), "lnt"] + + +func test_encode_mindblowingly(solution_script): + return [solution_script.encode("mindblowingly"), "nrmwy oldrm tob"] + + +func test_encode_numbers(solution_script): + return [solution_script.encode("Testing,1 2 3, testing."), "gvhgr mt123 gvhgr mt"] + + +func test_encode_deep_thought(solution_script): + return [solution_script.encode("Truth is fiction."), "gifgs rhurx grlm"] + + +func test_encode_all_the_letters(solution_script): + return [ + solution_script.encode("The quick brown fox jumps over the lazy dog."), + "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt", + ] + + +func test_decode_exercism(solution_script): + return [solution_script.decode("vcvix rhn"), "exercism"] + + +func test_decode_a_sentence(solution_script): + return [ + solution_script.decode("zmlyh gzxov rhlug vmzhg vkkrm thglm v"), + "anobstacleisoftenasteppingstone", + ] + + +func test_decode_numbers(solution_script): + return [solution_script.decode("gvhgr mt123 gvhgr mt"), "testing123testing"] + + +func test_decode_all_the_letters(solution_script): + return [ + solution_script.decode("gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt"), + "thequickbrownfoxjumpsoverthelazydog", + ] + + +func test_decode_with_too_many_spaces(solution_script): + return [solution_script.decode("vc vix r hn"), "exercism"] + + +func test_decode_with_no_spaces(solution_script): + return [ + solution_script.decode("zmlyhgzxovrhlugvmzhgvkkrmthglmv"), "anobstacleisoftenasteppingstone" + ] + + From ca81afc881d1e295171cb74af18a6323e04b34e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=C2=A0Fertyk?= Date: Tue, 6 Feb 2024 18:05:21 +0100 Subject: [PATCH 30/33] Add binary-search exercise (#48) --- config.json | 8 ++++ .../binary-search/.docs/instructions.md | 29 ++++++++++++ .../binary-search/.docs/introduction.md | 13 ++++++ .../practice/binary-search/.meta/config.json | 19 ++++++++ .../practice/binary-search/.meta/example.gd | 12 +++++ .../practice/binary-search/.meta/tests.toml | 43 ++++++++++++++++++ .../practice/binary-search/binary_search.gd | 2 + .../binary-search/binary_search_test.gd | 44 +++++++++++++++++++ 8 files changed, 170 insertions(+) create mode 100644 exercises/practice/binary-search/.docs/instructions.md create mode 100644 exercises/practice/binary-search/.docs/introduction.md create mode 100644 exercises/practice/binary-search/.meta/config.json create mode 100644 exercises/practice/binary-search/.meta/example.gd create mode 100644 exercises/practice/binary-search/.meta/tests.toml create mode 100644 exercises/practice/binary-search/binary_search.gd create mode 100644 exercises/practice/binary-search/binary_search_test.gd diff --git a/config.json b/config.json index cdd15ed..b844e15 100644 --- a/config.json +++ b/config.json @@ -131,6 +131,14 @@ "prerequisites": [], "difficulty": 2 }, + { + "slug": "binary-search", + "name": "Binary Search", + "uuid": "cce06bc1-255a-4a7b-a3e2-7d5e3d2445f3", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "luhn", "name": "Luhn", diff --git a/exercises/practice/binary-search/.docs/instructions.md b/exercises/practice/binary-search/.docs/instructions.md new file mode 100644 index 0000000..12f4358 --- /dev/null +++ b/exercises/practice/binary-search/.docs/instructions.md @@ -0,0 +1,29 @@ +# Instructions + +Your task is to implement a binary search algorithm. + +A 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. +It allows us to quickly narrow down the possible locations of our item until we find it, or until we've eliminated all possible locations. + +~~~~exercism/caution +Binary search only works when a list has been sorted. +~~~~ + +The algorithm looks like this: + +- Find the middle element of a _sorted_ list and compare it with the item we're looking for. +- If the middle element is our item, then we're done! +- If the middle element is greater than our item, we can eliminate that element and all the elements **after** it. +- If the middle element is less than our item, we can eliminate that element and all the elements **before** it. +- If every element of the list has been eliminated then the item is not in the list. +- Otherwise, repeat the process on the part of the list that has not been eliminated. + +Here's an example: + +Let's say we're looking for the number 23 in the following sorted list: `[4, 8, 12, 16, 23, 28, 32]`. + +- We start by comparing 23 with the middle element, 16. +- Since 23 is greater than 16, we can eliminate the left half of the list, leaving us with `[23, 28, 32]`. +- We then compare 23 with the new middle element, 28. +- Since 23 is less than 28, we can eliminate the right half of the list: `[23]`. +- We've found our item. diff --git a/exercises/practice/binary-search/.docs/introduction.md b/exercises/practice/binary-search/.docs/introduction.md new file mode 100644 index 0000000..0349659 --- /dev/null +++ b/exercises/practice/binary-search/.docs/introduction.md @@ -0,0 +1,13 @@ +# Introduction + +You have stumbled upon a group of mathematicians who are also singer-songwriters. +They 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]). + +You 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. +Fortunately, they have organized their songs in a playlist sorted by the title — which is simply the number that the song is about. + +You realize that you can use a binary search algorithm to quickly find a song given the title. + +[zero]: https://en.wikipedia.org/wiki/0 +[seventy-three]: https://en.wikipedia.org/wiki/73_(number) +[kaprekars-constant]: https://en.wikipedia.org/wiki/6174_(number) diff --git a/exercises/practice/binary-search/.meta/config.json b/exercises/practice/binary-search/.meta/config.json new file mode 100644 index 0000000..e3db785 --- /dev/null +++ b/exercises/practice/binary-search/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "pfertyk" + ], + "files": { + "solution": [ + "binary_search.gd" + ], + "test": [ + "binary_search_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Implement a binary search algorithm.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Binary_search_algorithm" +} diff --git a/exercises/practice/binary-search/.meta/example.gd b/exercises/practice/binary-search/.meta/example.gd new file mode 100644 index 0000000..19b6b8a --- /dev/null +++ b/exercises/practice/binary-search/.meta/example.gd @@ -0,0 +1,12 @@ +func find(search_list, value): + var low = 0 + var high = len(search_list) - 1 + while low <= high: + var middle = (low + high) / 2 + if search_list[middle] > value: + high = middle - 1 + elif search_list[middle] < value: + low = middle + 1 + else: + return middle + return false diff --git a/exercises/practice/binary-search/.meta/tests.toml b/exercises/practice/binary-search/.meta/tests.toml new file mode 100644 index 0000000..61e2b06 --- /dev/null +++ b/exercises/practice/binary-search/.meta/tests.toml @@ -0,0 +1,43 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[b55c24a9-a98d-4379-a08c-2adcf8ebeee8] +description = "finds a value in an array with one element" + +[73469346-b0a0-4011-89bf-989e443d503d] +description = "finds a value in the middle of an array" + +[327bc482-ab85-424e-a724-fb4658e66ddb] +description = "finds a value at the beginning of an array" + +[f9f94b16-fe5e-472c-85ea-c513804c7d59] +description = "finds a value at the end of an array" + +[f0068905-26e3-4342-856d-ad153cadb338] +description = "finds a value in an array of odd length" + +[fc316b12-c8b3-4f5e-9e89-532b3389de8c] +description = "finds a value in an array of even length" + +[da7db20a-354f-49f7-a6a1-650a54998aa6] +description = "identifies that a value is not included in the array" + +[95d869ff-3daf-4c79-b622-6e805c675f97] +description = "a value smaller than the array's smallest value is not found" + +[8b24ef45-6e51-4a94-9eac-c2bf38fdb0ba] +description = "a value larger than the array's largest value is not found" + +[f439a0fa-cf42-4262-8ad1-64bf41ce566a] +description = "nothing is found in an empty array" + +[2c353967-b56d-40b8-acff-ce43115eed64] +description = "nothing is found when the left and right bounds cross" diff --git a/exercises/practice/binary-search/binary_search.gd b/exercises/practice/binary-search/binary_search.gd new file mode 100644 index 0000000..028218c --- /dev/null +++ b/exercises/practice/binary-search/binary_search.gd @@ -0,0 +1,2 @@ +func find(search_list, value): + pass diff --git a/exercises/practice/binary-search/binary_search_test.gd b/exercises/practice/binary-search/binary_search_test.gd new file mode 100644 index 0000000..fc1431b --- /dev/null +++ b/exercises/practice/binary-search/binary_search_test.gd @@ -0,0 +1,44 @@ +func test_finds_a_value_in_an_array_with_one_element(solution_script): + return [solution_script.find([6], 6), 0] + + +func test_finds_a_value_in_the_middle_of_an_array(solution_script): + return [solution_script.find([1, 3, 4, 6, 8, 9, 11], 6), 3] + + +func test_finds_a_value_at_the_beginning_of_an_array(solution_script): + return [solution_script.find([1, 3, 4, 6, 8, 9, 11], 1), 0] + + +func test_finds_a_value_at_the_end_of_an_array(solution_script): + return [solution_script.find([1, 3, 4, 6, 8, 9, 11], 11), 6] + + +func test_finds_a_value_in_an_array_of_odd_length(solution_script): + return [ + solution_script.find([1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 634], 144), 9 + ] + + +func test_finds_a_value_in_an_array_of_even_length(solution_script): + return [solution_script.find([1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377], 21), 5] + + +func test_identifies_that_a_value_is_not_included_in_the_array(solution_script): + return [solution_script.find([1, 3, 4, 6, 8, 9, 11], 7), false] + + +func test_a_value_smaller_than_the_array_s_smallest_value_is_not_found(solution_script): + return [solution_script.find([1, 3, 4, 6, 8, 9, 11], 0), false] + + +func test_a_value_larger_than_the_array_s_largest_value_is_not_found(solution_script): + return [solution_script.find([1, 3, 4, 6, 8, 9, 11], 13), false] + + +func test_nothing_is_found_in_an_empty_array(solution_script): + return [solution_script.find([], 1), false] + + +func test_nothing_is_found_when_the_left_and_right_bounds_cross(solution_script): + return [solution_script.find([1, 2], 0), false] From dcc3f976e005868d7692fc601eb4c027f1a2fcd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=C2=A0Fertyk?= Date: Sat, 10 Feb 2024 17:30:57 +0100 Subject: [PATCH 31/33] Add allergies exercise (#44) --- config.json | 8 + .../practice/allergies/.docs/instructions.md | 27 ++ .../practice/allergies/.meta/config.json | 19 ++ exercises/practice/allergies/.meta/example.gd | 28 ++ exercises/practice/allergies/.meta/tests.toml | 160 ++++++++++ exercises/practice/allergies/allergies.gd | 12 + .../practice/allergies/allergies_test.gd | 279 ++++++++++++++++++ 7 files changed, 533 insertions(+) create mode 100644 exercises/practice/allergies/.docs/instructions.md create mode 100644 exercises/practice/allergies/.meta/config.json create mode 100644 exercises/practice/allergies/.meta/example.gd create mode 100644 exercises/practice/allergies/.meta/tests.toml create mode 100644 exercises/practice/allergies/allergies.gd create mode 100644 exercises/practice/allergies/allergies_test.gd diff --git a/config.json b/config.json index b844e15..7401f06 100644 --- a/config.json +++ b/config.json @@ -153,6 +153,14 @@ "uuid": "3a40dd65-7b56-4e0f-aed6-0e0a28753ca9", "practices": [], "prerequisites": [], + "difficulty": 2 + }, + { + "slug": "allergies", + "name": "Allergies", + "uuid": "a7d7c899-ece3-4a4d-9a5b-d7c1ae367b0a", + "practices": [], + "prerequisites": [], "difficulty": 3 } ] diff --git a/exercises/practice/allergies/.docs/instructions.md b/exercises/practice/allergies/.docs/instructions.md new file mode 100644 index 0000000..daf8cfd --- /dev/null +++ b/exercises/practice/allergies/.docs/instructions.md @@ -0,0 +1,27 @@ +# Instructions + +Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies. + +An allergy test produces a single numeric score which contains the information about all the allergies the person has (that they were tested for). + +The list of items (and their value) that were tested are: + +- eggs (1) +- peanuts (2) +- shellfish (4) +- strawberries (8) +- tomatoes (16) +- chocolate (32) +- pollen (64) +- cats (128) + +So if Tom is allergic to peanuts and chocolate, he gets a score of 34. + +Now, given just that score of 34, your program should be able to say: + +- Whether Tom is allergic to any one of those allergens listed above. +- All the allergens Tom is allergic to. + +Note: a given score may include allergens **not** listed above (i.e. allergens that score 256, 512, 1024, etc.). +Your program should ignore those components of the score. +For example, if the allergy score is 257, your program should only report the eggs (1) allergy. diff --git a/exercises/practice/allergies/.meta/config.json b/exercises/practice/allergies/.meta/config.json new file mode 100644 index 0000000..143976a --- /dev/null +++ b/exercises/practice/allergies/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "pfertyk" + ], + "files": { + "solution": [ + "allergies.gd" + ], + "test": [ + "allergies_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies.", + "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", + "source_url": "https://turing.edu" +} diff --git a/exercises/practice/allergies/.meta/example.gd b/exercises/practice/allergies/.meta/example.gd new file mode 100644 index 0000000..5691284 --- /dev/null +++ b/exercises/practice/allergies/.meta/example.gd @@ -0,0 +1,28 @@ +@export var score : int +@export var lst: Array: get = _get_lst + +const ALLERGENS = [ + "eggs", + "peanuts", + "shellfish", + "strawberries", + "tomatoes", + "chocolate", + "pollen", + "cats", +] + + + +func allergic_to(item): + var index = ALLERGENS.find(item) + return bool(1 << index & score) + + + +func _get_lst(): + var allergies = [] + for item in ALLERGENS: + if allergic_to(item): + allergies.append(item) + return allergies diff --git a/exercises/practice/allergies/.meta/tests.toml b/exercises/practice/allergies/.meta/tests.toml new file mode 100644 index 0000000..799ab85 --- /dev/null +++ b/exercises/practice/allergies/.meta/tests.toml @@ -0,0 +1,160 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[17fc7296-2440-4ac4-ad7b-d07c321bc5a0] +description = "testing for eggs allergy -> not allergic to anything" + +[07ced27b-1da5-4c2e-8ae2-cb2791437546] +description = "testing for eggs allergy -> allergic only to eggs" + +[5035b954-b6fa-4b9b-a487-dae69d8c5f96] +description = "testing for eggs allergy -> allergic to eggs and something else" + +[64a6a83a-5723-4b5b-a896-663307403310] +description = "testing for eggs allergy -> allergic to something, but not eggs" + +[90c8f484-456b-41c4-82ba-2d08d93231c6] +description = "testing for eggs allergy -> allergic to everything" + +[d266a59a-fccc-413b-ac53-d57cb1f0db9d] +description = "testing for peanuts allergy -> not allergic to anything" + +[ea210a98-860d-46b2-a5bf-50d8995b3f2a] +description = "testing for peanuts allergy -> allergic only to peanuts" + +[eac69ae9-8d14-4291-ac4b-7fd2c73d3a5b] +description = "testing for peanuts allergy -> allergic to peanuts and something else" + +[9152058c-ce39-4b16-9b1d-283ec6d25085] +description = "testing for peanuts allergy -> allergic to something, but not peanuts" + +[d2d71fd8-63d5-40f9-a627-fbdaf88caeab] +description = "testing for peanuts allergy -> allergic to everything" + +[b948b0a1-cbf7-4b28-a244-73ff56687c80] +description = "testing for shellfish allergy -> not allergic to anything" + +[9ce9a6f3-53e9-4923-85e0-73019047c567] +description = "testing for shellfish allergy -> allergic only to shellfish" + +[b272fca5-57ba-4b00-bd0c-43a737ab2131] +description = "testing for shellfish allergy -> allergic to shellfish and something else" + +[21ef8e17-c227-494e-8e78-470a1c59c3d8] +description = "testing for shellfish allergy -> allergic to something, but not shellfish" + +[cc789c19-2b5e-4c67-b146-625dc8cfa34e] +description = "testing for shellfish allergy -> allergic to everything" + +[651bde0a-2a74-46c4-ab55-02a0906ca2f5] +description = "testing for strawberries allergy -> not allergic to anything" + +[b649a750-9703-4f5f-b7f7-91da2c160ece] +description = "testing for strawberries allergy -> allergic only to strawberries" + +[50f5f8f3-3bac-47e6-8dba-2d94470a4bc6] +description = "testing for strawberries allergy -> allergic to strawberries and something else" + +[23dd6952-88c9-48d7-a7d5-5d0343deb18d] +description = "testing for strawberries allergy -> allergic to something, but not strawberries" + +[74afaae2-13b6-43a2-837a-286cd42e7d7e] +description = "testing for strawberries allergy -> allergic to everything" + +[c49a91ef-6252-415e-907e-a9d26ef61723] +description = "testing for tomatoes allergy -> not allergic to anything" + +[b69c5131-b7d0-41ad-a32c-e1b2cc632df8] +description = "testing for tomatoes allergy -> allergic only to tomatoes" + +[1ca50eb1-f042-4ccf-9050-341521b929ec] +description = "testing for tomatoes allergy -> allergic to tomatoes and something else" + +[e9846baa-456b-4eff-8025-034b9f77bd8e] +description = "testing for tomatoes allergy -> allergic to something, but not tomatoes" + +[b2414f01-f3ad-4965-8391-e65f54dad35f] +description = "testing for tomatoes allergy -> allergic to everything" + +[978467ab-bda4-49f7-b004-1d011ead947c] +description = "testing for chocolate allergy -> not allergic to anything" + +[59cf4e49-06ea-4139-a2c1-d7aad28f8cbc] +description = "testing for chocolate allergy -> allergic only to chocolate" + +[b0a7c07b-2db7-4f73-a180-565e07040ef1] +description = "testing for chocolate allergy -> allergic to chocolate and something else" + +[f5506893-f1ae-482a-b516-7532ba5ca9d2] +description = "testing for chocolate allergy -> allergic to something, but not chocolate" + +[02debb3d-d7e2-4376-a26b-3c974b6595c6] +description = "testing for chocolate allergy -> allergic to everything" + +[17f4a42b-c91e-41b8-8a76-4797886c2d96] +description = "testing for pollen allergy -> not allergic to anything" + +[7696eba7-1837-4488-882a-14b7b4e3e399] +description = "testing for pollen allergy -> allergic only to pollen" + +[9a49aec5-fa1f-405d-889e-4dfc420db2b6] +description = "testing for pollen allergy -> allergic to pollen and something else" + +[3cb8e79f-d108-4712-b620-aa146b1954a9] +description = "testing for pollen allergy -> allergic to something, but not pollen" + +[1dc3fe57-7c68-4043-9d51-5457128744b2] +description = "testing for pollen allergy -> allergic to everything" + +[d3f523d6-3d50-419b-a222-d4dfd62ce314] +description = "testing for cats allergy -> not allergic to anything" + +[eba541c3-c886-42d3-baef-c048cb7fcd8f] +description = "testing for cats allergy -> allergic only to cats" + +[ba718376-26e0-40b7-bbbe-060287637ea5] +description = "testing for cats allergy -> allergic to cats and something else" + +[3c6dbf4a-5277-436f-8b88-15a206f2d6c4] +description = "testing for cats allergy -> allergic to something, but not cats" + +[1faabb05-2b98-4995-9046-d83e4a48a7c1] +description = "testing for cats allergy -> allergic to everything" + +[f9c1b8e7-7dc5-4887-aa93-cebdcc29dd8f] +description = "list when: -> no allergies" + +[9e1a4364-09a6-4d94-990f-541a94a4c1e8] +description = "list when: -> just eggs" + +[8851c973-805e-4283-9e01-d0c0da0e4695] +description = "list when: -> just peanuts" + +[2c8943cb-005e-435f-ae11-3e8fb558ea98] +description = "list when: -> just strawberries" + +[6fa95d26-044c-48a9-8a7b-9ee46ec32c5c] +description = "list when: -> eggs and peanuts" + +[19890e22-f63f-4c5c-a9fb-fb6eacddfe8e] +description = "list when: -> more than eggs but not peanuts" + +[4b68f470-067c-44e4-889f-c9fe28917d2f] +description = "list when: -> lots of stuff" + +[0881b7c5-9efa-4530-91bd-68370d054bc7] +description = "list when: -> everything" + +[12ce86de-b347-42a0-ab7c-2e0570f0c65b] +description = "list when: -> no allergen score parts" + +[93c2df3e-4f55-4fed-8116-7513092819cd] +description = "list when: -> no allergen score parts without highest valid score" diff --git a/exercises/practice/allergies/allergies.gd b/exercises/practice/allergies/allergies.gd new file mode 100644 index 0000000..ae14162 --- /dev/null +++ b/exercises/practice/allergies/allergies.gd @@ -0,0 +1,12 @@ +@export var score : int +@export var lst: Array: get = _get_lst + + + +func allergic_to(item): + pass + + + +func _get_lst(): + pass diff --git a/exercises/practice/allergies/allergies_test.gd b/exercises/practice/allergies/allergies_test.gd new file mode 100644 index 0000000..c8378da --- /dev/null +++ b/exercises/practice/allergies/allergies_test.gd @@ -0,0 +1,279 @@ +func _sorted(array): + # Array.sort() sorts an array in place and returns null. + # This helper method allows us to sort and compare in the same line. + array.sort() + return array + + +# testing for eggs allergy + +func test_eggs_not_allergic_to_anything(allergies): + allergies.score = 0 + return [allergies.allergic_to("eggs"), false] + + +func test_eggs_allergic_only_to_eggs(allergies): + allergies.score = 1 + return [allergies.allergic_to("eggs"), true] + + +func test_eggs_allergic_to_eggs_and_something_else(allergies): + allergies.score = 3 + return [allergies.allergic_to("eggs"), true] + + +func test_eggs_allergic_to_something_but_not_eggs(allergies): + allergies.score = 2 + return [allergies.allergic_to("eggs"), false] + + +func test_eggs_allergic_to_everything(allergies): + allergies.score = 255 + return [allergies.allergic_to("eggs"), true] + + +# testing for peanuts allergy + +func test_peanuts_not_allergic_to_anything(allergies): + allergies.score = 0 + return [allergies.allergic_to("peanuts"), false] + + +func test_peanuts_allergic_only_to_peanuts(allergies): + allergies.score = 2 + return [allergies.allergic_to("peanuts"), true] + + +func test_peanuts_allergic_to_peanuts_and_something_else(allergies): + allergies.score = 7 + return [allergies.allergic_to("peanuts"), true] + + +func test_peanuts_allergic_to_something_but_not_peanuts(allergies): + allergies.score = 5 + return [allergies.allergic_to("peanuts"), false] + + +func test_peanuts_allergic_to_everything(allergies): + allergies.score = 255 + return [allergies.allergic_to("peanuts"), true] + + +# testing for shellfish allergy + +func test_shellfish_not_allergic_to_anything(allergies): + allergies.score = 0 + return [allergies.allergic_to("shellfish"), false] + + +func test_shellfish_allergic_only_to_shellfish(allergies): + allergies.score = 4 + return [allergies.allergic_to("shellfish"), true] + + +func test_shellfish_allergic_to_shellfish_and_something_else(allergies): + allergies.score = 14 + return [allergies.allergic_to("shellfish"), true] + + +func test_shellfish_allergic_to_something_but_not_shellfish(allergies): + allergies.score = 10 + return [allergies.allergic_to("shellfish"), false] + + +func test_shellfish_allergic_to_everything(allergies): + allergies.score = 255 + return [allergies.allergic_to("shellfish"), true] + + +# testing for strawberries allergy + +func test_strawberries_not_allergic_to_anything(allergies): + allergies.score = 0 + return [allergies.allergic_to("strawberries"), false] + + +func test_strawberries_allergic_only_to_strawberries(allergies): + allergies.score = 8 + return [allergies.allergic_to("strawberries"), true] + + +func test_strawberries_allergic_to_strawberries_and_something_else(allergies): + allergies.score = 28 + return [allergies.allergic_to("strawberries"), true] + + +func test_strawberries_allergic_to_something_but_not_strawberries(allergies): + allergies.score = 20 + return [allergies.allergic_to("strawberries"), false] + + +func test_strawberries_allergic_to_everything(allergies): + allergies.score = 255 + return [allergies.allergic_to("strawberries"), true] + + +# testing for tomatoes allergy + +func test_tomatoes_not_allergic_to_anything(allergies): + allergies.score = 0 + return [allergies.allergic_to("tomatoes"), false] + + +func test_tomatoes_allergic_only_to_tomatoes(allergies): + allergies.score = 16 + return [allergies.allergic_to("tomatoes"), true] + + +func test_tomatoes_allergic_to_tomatoes_and_something_else(allergies): + allergies.score = 56 + return [allergies.allergic_to("tomatoes"), true] + + +func test_tomatoes_allergic_to_something_but_not_tomatoes(allergies): + allergies.score = 40 + return [allergies.allergic_to("tomatoes"), false] + + +func test_tomatoes_allergic_to_everything(allergies): + allergies.score = 255 + return [allergies.allergic_to("tomatoes"), true] + + +# testing for chocolate allergy + +func test_chocolate_not_allergic_to_anything(allergies): + allergies.score = 0 + return [allergies.allergic_to("chocolate"), false] + + +func test_chocolate_allergic_only_to_chocolate(allergies): + allergies.score = 32 + return [allergies.allergic_to("chocolate"), true] + + +func test_chocolate_allergic_to_chocolate_and_something_else(allergies): + allergies.score = 112 + return [allergies.allergic_to("chocolate"), true] + + +func test_chocolate_allergic_to_something_but_not_chocolate(allergies): + allergies.score = 80 + return [allergies.allergic_to("chocolate"), false] + + +func test_chocolate_allergic_to_everything(allergies): + allergies.score = 255 + return [allergies.allergic_to("chocolate"), true] + + +# testing for pollen allergy + +func test_pollen_not_allergic_to_anything(allergies): + allergies.score = 0 + return [allergies.allergic_to("pollen"), false] + + +func test_pollen_allergic_only_to_pollen(allergies): + allergies.score = 64 + return [allergies.allergic_to("pollen"), true] + + +func test_pollen_allergic_to_pollen_and_something_else(allergies): + allergies.score = 224 + return [allergies.allergic_to("pollen"), true] + + +func test_pollen_allergic_to_something_but_not_pollen(allergies): + allergies.score = 160 + return [allergies.allergic_to("pollen"), false] + + +func test_pollen_allergic_to_everything(allergies): + allergies.score = 255 + return [allergies.allergic_to("pollen"), true] + + +# testing for cats allergy + +func test_cats_not_allergic_to_anything(allergies): + allergies.score = 0 + return [allergies.allergic_to("cats"), false] + + +func test_cats_allergic_only_to_cats(allergies): + allergies.score = 128 + return [allergies.allergic_to("cats"), true] + + +func test_cats_allergic_to_cats_and_something_else(allergies): + allergies.score = 192 + return [allergies.allergic_to("cats"), true] + + +func test_cats_allergic_to_something_but_not_cats(allergies): + allergies.score = 64 + return [allergies.allergic_to("cats"), false] + + +func test_cats_allergic_to_everything(allergies): + allergies.score = 255 + return [allergies.allergic_to("cats"), true] + + +# list when: + +func test_list_when_no_allergies(allergies): + allergies.score = 0 + return [allergies.lst, []] + + +func test_list_when_just_eggs(allergies): + allergies.score = 1 + return [allergies.lst, ["eggs"]] + + +func test_list_when_just_peanuts(allergies): + allergies.score = 2 + return [allergies.lst, ["peanuts"]] + + +func test_list_when_just_strawberries(allergies): + allergies.score = 8 + return [allergies.lst, ["strawberries"]] + + +func test_list_when_eggs_and_peanuts(allergies): + allergies.score = 3 + return [_sorted(allergies.lst), ["eggs", "peanuts"]] + + +func test_list_when_more_than_eggs_but_not_peanuts(allergies): + allergies.score = 5 + return [_sorted(allergies.lst), ["eggs", "shellfish"]] + + +func test_list_when_lots_of_stuff(allergies): + allergies.score = 248 + return [_sorted(allergies.lst), ["cats", "chocolate", "pollen", "strawberries", "tomatoes"]] + + +func test_list_when_everything(allergies): + allergies.score = 255 + return [ + _sorted(allergies.lst), + ["cats", "chocolate", "eggs", "peanuts", "pollen", "shellfish", "strawberries", "tomatoes"] + ] + + +func test_list_when_no_allergen_score_parts(allergies): + allergies.score = 509 + return [ + _sorted(allergies.lst), + ["cats", "chocolate", "eggs", "pollen", "shellfish", "strawberries", "tomatoes"] + ] + + +func test_list_when_no_allergen_score_parts_without_highest_valid_score(allergies): + allergies.score = 257 + return [allergies.lst, ["eggs"]] From 4280977e69cd0139cdc96d801d3c9f0284852ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Sat, 10 Feb 2024 09:40:13 -0800 Subject: [PATCH 32/33] Add robot-simulator (#32) --- config.json | 8 + .../robot-simulator/.docs/instructions.md | 25 +++ .../robot-simulator/.meta/config.json | 21 +++ .../practice/robot-simulator/.meta/example.gd | 25 +++ .../practice/robot-simulator/.meta/tests.toml | 64 +++++++ .../robot-simulator/robot_simulator.gd | 6 + .../robot-simulator/robot_simulator_test.gd | 158 ++++++++++++++++++ 7 files changed, 307 insertions(+) create mode 100644 exercises/practice/robot-simulator/.docs/instructions.md create mode 100644 exercises/practice/robot-simulator/.meta/config.json create mode 100644 exercises/practice/robot-simulator/.meta/example.gd create mode 100644 exercises/practice/robot-simulator/.meta/tests.toml create mode 100644 exercises/practice/robot-simulator/robot_simulator.gd create mode 100644 exercises/practice/robot-simulator/robot_simulator_test.gd diff --git a/config.json b/config.json index 7401f06..bf85753 100644 --- a/config.json +++ b/config.json @@ -162,6 +162,14 @@ "practices": [], "prerequisites": [], "difficulty": 3 + }, + { + "slug": "robot-simulator", + "name": "Robot Simulator", + "uuid": "31a8cb4a-c211-4daa-a14b-7347fed015a6", + "practices": [], + "prerequisites": [], + "difficulty": 3 } ] }, diff --git a/exercises/practice/robot-simulator/.docs/instructions.md b/exercises/practice/robot-simulator/.docs/instructions.md new file mode 100644 index 0000000..0ac96ce --- /dev/null +++ b/exercises/practice/robot-simulator/.docs/instructions.md @@ -0,0 +1,25 @@ +# Instructions + +Write a robot simulator. + +A robot factory's test facility needs a program to verify robot movements. + +The robots have three possible movements: + +- turn right +- turn left +- advance + +Robots are placed on a hypothetical infinite grid, facing a particular direction (north, east, south, or west) at a set of {x,y} coordinates, +e.g., {3,8}, with coordinates increasing to the north and east. + +The 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. + +- The letter-string "RAALAL" means: + - Turn right + - Advance twice + - Turn left + - Advance once + - Turn left yet again +- Say a robot starts at {7, 3} facing north. + Then running this stream of instructions should leave it at {9, 4} facing west. diff --git a/exercises/practice/robot-simulator/.meta/config.json b/exercises/practice/robot-simulator/.meta/config.json new file mode 100644 index 0000000..712bc05 --- /dev/null +++ b/exercises/practice/robot-simulator/.meta/config.json @@ -0,0 +1,21 @@ +{ + "authors": [ + "BNAndras" + ], + "contributors": [ + "pfertyk" + ], + "files": { + "solution": [ + "robot_simulator.gd" + ], + "test": [ + "robot_simulator_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Write a robot simulator.", + "source": "Inspired by an interview question at a famous company." +} diff --git a/exercises/practice/robot-simulator/.meta/example.gd b/exercises/practice/robot-simulator/.meta/example.gd new file mode 100644 index 0000000..cce3a3b --- /dev/null +++ b/exercises/practice/robot-simulator/.meta/example.gd @@ -0,0 +1,25 @@ +@export var position : Vector2i +@export var direction : String + + +var allowed_directions = ["north", "east", "south", "west"] + + +func move(instructions: String): + for instruction in instructions: + match [instruction, direction]: + ["L", _]: + var index = allowed_directions.find(direction) - 1 + direction = allowed_directions[index] + ["R", _]: + var index = allowed_directions.find(direction) + index = (index + 1) % 4 + direction = allowed_directions[index] + ["A", "north"]: + position += Vector2i(0, 1) + ["A", "south"]: + position += Vector2i(0, -1) + ["A", "east"]: + position += Vector2i(1, 0) + ["A", "west"]: + position += Vector2i(-1, 0) diff --git a/exercises/practice/robot-simulator/.meta/tests.toml b/exercises/practice/robot-simulator/.meta/tests.toml new file mode 100644 index 0000000..16da03d --- /dev/null +++ b/exercises/practice/robot-simulator/.meta/tests.toml @@ -0,0 +1,64 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[c557c16d-26c1-4e06-827c-f6602cd0785c] +description = "Create robot -> at origin facing north" + +[bf0dffce-f11c-4cdb-8a5e-2c89d8a5a67d] +description = "Create robot -> at negative position facing south" + +[8cbd0086-6392-4680-b9b9-73cf491e67e5] +description = "Rotating clockwise -> changes north to east" + +[8abc87fc-eab2-4276-93b7-9c009e866ba1] +description = "Rotating clockwise -> changes east to south" + +[3cfe1b85-bbf2-4bae-b54d-d73e7e93617a] +description = "Rotating clockwise -> changes south to west" + +[5ea9fb99-3f2c-47bd-86f7-46b7d8c3c716] +description = "Rotating clockwise -> changes west to north" + +[fa0c40f5-6ba3-443d-a4b3-58cbd6cb8d63] +description = "Rotating counter-clockwise -> changes north to west" + +[da33d734-831f-445c-9907-d66d7d2a92e2] +description = "Rotating counter-clockwise -> changes west to south" + +[bd1ca4b9-4548-45f4-b32e-900fc7c19389] +description = "Rotating counter-clockwise -> changes south to east" + +[2de27b67-a25c-4b59-9883-bc03b1b55bba] +description = "Rotating counter-clockwise -> changes east to north" + +[f0dc2388-cddc-4f83-9bed-bcf46b8fc7b8] +description = "Moving forward one -> facing north increments Y" + +[2786cf80-5bbf-44b0-9503-a89a9c5789da] +description = "Moving forward one -> facing south decrements Y" + +[84bf3c8c-241f-434d-883d-69817dbd6a48] +description = "Moving forward one -> facing east increments X" + +[bb69c4a7-3bbf-4f64-b415-666fa72d7b04] +description = "Moving forward one -> facing west decrements X" + +[e34ac672-4ed4-4be3-a0b8-d9af259cbaa1] +description = "Follow series of instructions -> moving east and north from README" + +[f30e4955-4b47-4aa3-8b39-ae98cfbd515b] +description = "Follow series of instructions -> moving west and north" + +[3e466bf6-20ab-4d79-8b51-264165182fca] +description = "Follow series of instructions -> moving west and south" + +[41f0bb96-c617-4e6b-acff-a4b279d44514] +description = "Follow series of instructions -> moving east and north" diff --git a/exercises/practice/robot-simulator/robot_simulator.gd b/exercises/practice/robot-simulator/robot_simulator.gd new file mode 100644 index 0000000..07048c1 --- /dev/null +++ b/exercises/practice/robot-simulator/robot_simulator.gd @@ -0,0 +1,6 @@ +@export var position : Vector2i +@export var direction : String + + +func move(instructions: String): + pass diff --git a/exercises/practice/robot-simulator/robot_simulator_test.gd b/exercises/practice/robot-simulator/robot_simulator_test.gd new file mode 100644 index 0000000..5bfda42 --- /dev/null +++ b/exercises/practice/robot-simulator/robot_simulator_test.gd @@ -0,0 +1,158 @@ +func test_create_robot_at_origin_facing_north(robot): + robot.position = Vector2i(0, 0) + robot.direction = "north" + var result = [robot.position, robot.direction] + var expected = [Vector2i(0, 0), "north"] + return [expected, result] + + +func test_create_robot_at_negative_position_facing_south(robot): + robot.position = Vector2i(-1, -1) + robot.direction = "south" + var result = [robot.position, robot.direction] + var expected = [Vector2i(-1, -1), "south"] + return [expected, result] + + +func test_rotating_clockwise_changes_north_to_east(robot): + robot.position = Vector2i(0, 0) + robot.direction = "north" + robot.move("R") + var result = [robot.position, robot.direction] + var expected = [Vector2i(0, 0), "east"] + return [expected, result] + + +func test_rotating_clockwise_changes_east_to_south(robot): + robot.position = Vector2i(0, 0) + robot.direction = "east" + robot.move("R") + var result = [robot.position, robot.direction] + var expected = [Vector2i(0, 0), "south"] + return [expected, result] + + +func test_rotating_clockwise_changes_south_to_west(robot): + robot.position = Vector2i(0, 0) + robot.direction = "south" + robot.move("R") + var result = [robot.position, robot.direction] + var expected = [Vector2i(0, 0), "west"] + return [expected, result] + + +func test_rotating_clockwise_changes_west_to_north(robot): + robot.position = Vector2i(0, 0) + robot.direction = "west" + robot.move("R") + var result = [robot.position, robot.direction] + var expected = [Vector2i(0, 0), "north"] + return [expected, result] + + +func test_rotating_counterclockwise_changes_north_to_west(robot): + robot.position = Vector2i(0, 0) + robot.direction = "north" + robot.move("L") + var result = [robot.position, robot.direction] + var expected = [Vector2i(0, 0), "west"] + return [expected, result] + + +func test_rotating_counterclockwise_changes_west_to_south(robot): + robot.position = Vector2i(0, 0) + robot.direction = "west" + robot.move("L") + var result = [robot.position, robot.direction] + var expected = [Vector2i(0, 0), "south"] + return [expected, result] + + +func test_rotating_counterclockwise_changes_south_to_east(robot): + robot.position = Vector2i(0, 0) + robot.direction = "south" + robot.move("L") + var result = [robot.position, robot.direction] + var expected = [Vector2i(0, 0), "east"] + return [expected, result] + + +func test_rotating_counterclockwise_changes_east_to_north(robot): + robot.position = Vector2i(0, 0) + robot.direction = "east" + robot.move("L") + var result = [robot.position, robot.direction] + var expected = [Vector2i(0, 0), "north"] + return [expected, result] + + +func test_moving_forward_one_facing_north_increments_y(robot): + robot.position = Vector2i(0, 0) + robot.direction = "north" + robot.move("A") + var result = [robot.position, robot.direction] + var expected = [Vector2i(0, 1), "north"] + return [expected, result] + + +func test_moving_forward_one_facing_south_decrements_y(robot): + robot.position = Vector2i(0, 0) + robot.direction = "south" + robot.move("A") + var result = [robot.position, robot.direction] + var expected = [Vector2i(0, -1), "south"] + return [expected, result] + + +func test_moving_forward_one_facing_east_increments_x(robot): + robot.position = Vector2i(0, 0) + robot.direction = "east" + robot.move("A") + var result = [robot.position, robot.direction] + var expected = [Vector2i(1, 0), "east"] + return [expected, result] + + +func test_moving_forward_one_facing_west_decrements_x(robot): + robot.position = Vector2i(0, 0) + robot.direction = "west" + robot.move("A") + var result = [robot.position, robot.direction] + var expected = [Vector2i(-1, 0), "west"] + return [expected, result] + + +func test_moving_east_and_north_from_readme(robot): + robot.position = Vector2i(7, 3) + robot.direction = "north" + robot.move("RAALAL") + var result = [robot.position, robot.direction] + var expected = [Vector2i(9, 4), "west"] + return [expected, result] + + +func test_moving_west_and_north(robot): + robot.position = Vector2i(0, 0) + robot.direction = "north" + robot.move("LAAARALA") + var result = [robot.position, robot.direction] + var expected = [Vector2i(-4, 1), "west"] + return [expected, result] + + +func test_moving_west_and_south(robot): + robot.position = Vector2i(2, -7) + robot.direction = "east" + robot.move("RRAAAAALA") + var result = [robot.position, robot.direction] + var expected = [Vector2i(-3, -8), "south"] + return [expected, result] + + +func test_moving_east_and_north(robot): + robot.position = Vector2i(8, 4) + robot.direction = "south" + robot.move("LAAARRRALLLL") + var result = [robot.position, robot.direction] + var expected = [Vector2i(11, 5), "north"] + return [expected, result] From 04310389c7fefc3c3109328b42f06ea24ba0c8fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=C2=A0Fertyk?= Date: Sat, 10 Feb 2024 21:56:16 +0100 Subject: [PATCH 33/33] Add spiral-matrix exercise (#49) --- config.json | 8 +++ .../spiral-matrix/.docs/instructions.md | 24 +++++++++ .../practice/spiral-matrix/.meta/config.json | 19 +++++++ .../practice/spiral-matrix/.meta/example.gd | 23 ++++++++ .../practice/spiral-matrix/.meta/tests.toml | 28 ++++++++++ .../practice/spiral-matrix/spiral_matrix.gd | 2 + .../spiral-matrix/spiral_matrix_test.gd | 52 +++++++++++++++++++ 7 files changed, 156 insertions(+) create mode 100644 exercises/practice/spiral-matrix/.docs/instructions.md create mode 100644 exercises/practice/spiral-matrix/.meta/config.json create mode 100644 exercises/practice/spiral-matrix/.meta/example.gd create mode 100644 exercises/practice/spiral-matrix/.meta/tests.toml create mode 100644 exercises/practice/spiral-matrix/spiral_matrix.gd create mode 100644 exercises/practice/spiral-matrix/spiral_matrix_test.gd diff --git a/config.json b/config.json index bf85753..81a601c 100644 --- a/config.json +++ b/config.json @@ -170,6 +170,14 @@ "practices": [], "prerequisites": [], "difficulty": 3 + }, + { + "slug": "spiral-matrix", + "name": "Spiral Matrix", + "uuid": "7fbea4aa-0454-43a0-a189-4169b0f762e5", + "practices": [], + "prerequisites": [], + "difficulty": 4 } ] }, diff --git a/exercises/practice/spiral-matrix/.docs/instructions.md b/exercises/practice/spiral-matrix/.docs/instructions.md new file mode 100644 index 0000000..ba99e12 --- /dev/null +++ b/exercises/practice/spiral-matrix/.docs/instructions.md @@ -0,0 +1,24 @@ +# Instructions + +Given the size, return a square matrix of numbers in spiral order. + +The matrix should be filled with natural numbers, starting from 1 in the top-left corner, increasing in an inward, clockwise spiral order, like these examples: + +## Examples + +### Spiral matrix of size 3 + +```text +1 2 3 +8 9 4 +7 6 5 +``` + +### Spiral matrix of size 4 + +```text + 1 2 3 4 +12 13 14 5 +11 16 15 6 +10 9 8 7 +``` diff --git a/exercises/practice/spiral-matrix/.meta/config.json b/exercises/practice/spiral-matrix/.meta/config.json new file mode 100644 index 0000000..d270bbf --- /dev/null +++ b/exercises/practice/spiral-matrix/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "pfertyk" + ], + "files": { + "solution": [ + "spiral_matrix.gd" + ], + "test": [ + "spiral_matrix_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Given the size, return a square matrix of numbers in spiral order.", + "source": "Reddit r/dailyprogrammer challenge #320 [Easy] Spiral Ascension.", + "source_url": "https://web.archive.org/web/20230607064729/https://old.reddit.com/r/dailyprogrammer/comments/6i60lr/20170619_challenge_320_easy_spiral_ascension/" +} diff --git a/exercises/practice/spiral-matrix/.meta/example.gd b/exercises/practice/spiral-matrix/.meta/example.gd new file mode 100644 index 0000000..59074fd --- /dev/null +++ b/exercises/practice/spiral-matrix/.meta/example.gd @@ -0,0 +1,23 @@ +func spiral_matrix(size): + var matrix = [] + for i in range(size): + var row = [] + for j in range(size): + row.append(0) + matrix.append(row) + + var idx = 0 + var jdx = -1 + var element = 1 + + var digital = [0, 1, 0, -1] + var disco = [1, 0, -1, 0] + + for edx in range(2 * size - 1): + for i in range((2 * size - edx) / 2): + idx += digital[edx % 4] + jdx += disco[edx % 4] + matrix[idx][jdx] = element + element += 1 + + return matrix diff --git a/exercises/practice/spiral-matrix/.meta/tests.toml b/exercises/practice/spiral-matrix/.meta/tests.toml new file mode 100644 index 0000000..9ac5bac --- /dev/null +++ b/exercises/practice/spiral-matrix/.meta/tests.toml @@ -0,0 +1,28 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[8f584201-b446-4bc9-b132-811c8edd9040] +description = "empty spiral" + +[e40ae5f3-e2c9-4639-8116-8a119d632ab2] +description = "trivial spiral" + +[cf05e42d-eb78-4098-a36e-cdaf0991bc48] +description = "spiral of size 2" + +[1c475667-c896-4c23-82e2-e033929de939] +description = "spiral of size 3" + +[05ccbc48-d891-44f5-9137-f4ce462a759d] +description = "spiral of size 4" + +[f4d2165b-1738-4e0c-bed0-c459045ae50d] +description = "spiral of size 5" diff --git a/exercises/practice/spiral-matrix/spiral_matrix.gd b/exercises/practice/spiral-matrix/spiral_matrix.gd new file mode 100644 index 0000000..b3abdf1 --- /dev/null +++ b/exercises/practice/spiral-matrix/spiral_matrix.gd @@ -0,0 +1,2 @@ +func spiral_matrix(size): + pass diff --git a/exercises/practice/spiral-matrix/spiral_matrix_test.gd b/exercises/practice/spiral-matrix/spiral_matrix_test.gd new file mode 100644 index 0000000..0df5bba --- /dev/null +++ b/exercises/practice/spiral-matrix/spiral_matrix_test.gd @@ -0,0 +1,52 @@ +func test_empty_spiral(solution_script): + return [solution_script.spiral_matrix(0), []] + + +func test_trivial_spiral(solution_script): + return [solution_script.spiral_matrix(1), [[1]]] + + +func test_spiral_of_size_2(solution_script): + return [ + solution_script.spiral_matrix(2), + [ + [1, 2], + [4, 3] + ] + ] + + +func test_spiral_of_size_3(solution_script): + return [ + solution_script.spiral_matrix(3), + [ + [1, 2, 3], + [8, 9, 4], + [7, 6, 5] + ] + ] + + +func test_spiral_of_size_4(solution_script): + return [ + solution_script.spiral_matrix(4), + [ + [1, 2, 3, 4], + [12, 13, 14, 5], + [11, 16, 15, 6], + [10, 9, 8, 7] + ] + ] + + +func test_spiral_of_size_5(solution_script): + return [ + solution_script.spiral_matrix(5), + [ + [1, 2, 3, 4, 5], + [16, 17, 18, 19, 6], + [15, 24, 25, 20, 7], + [14, 23, 22, 21, 8], + [13, 12, 11, 10, 9], + ] + ]