From 20f17dce528d4117f9a89050c8f022ace9f2078d Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Sun, 27 Sep 2026 09:37:03 -0700 Subject: [PATCH] [etl] Add new practice exercise --- config.json | 8 ++ exercises/practice/etl/.docs/instructions.md | 27 +++++++ exercises/practice/etl/.docs/introduction.md | 16 ++++ exercises/practice/etl/.meta/config.json | 19 +++++ exercises/practice/etl/.meta/example.gd | 6 ++ exercises/practice/etl/.meta/template.j2 | 11 +++ exercises/practice/etl/.meta/tests.toml | 22 ++++++ exercises/practice/etl/etl.gd | 2 + exercises/practice/etl/etl_test.gd | 77 ++++++++++++++++++++ 9 files changed, 188 insertions(+) create mode 100644 exercises/practice/etl/.docs/instructions.md create mode 100644 exercises/practice/etl/.docs/introduction.md create mode 100644 exercises/practice/etl/.meta/config.json create mode 100644 exercises/practice/etl/.meta/example.gd create mode 100644 exercises/practice/etl/.meta/template.j2 create mode 100644 exercises/practice/etl/.meta/tests.toml create mode 100644 exercises/practice/etl/etl.gd create mode 100644 exercises/practice/etl/etl_test.gd diff --git a/config.json b/config.json index d9c275c..e05a153 100644 --- a/config.json +++ b/config.json @@ -266,6 +266,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "etl", + "name": "ETL", + "uuid": "47c88b96-c87f-4980-8ab4-ad14f45c36a7", + "practices": [], + "prerequisites": [], + "difficulty": 2 } ] }, diff --git a/exercises/practice/etl/.docs/instructions.md b/exercises/practice/etl/.docs/instructions.md new file mode 100644 index 0000000..802863b --- /dev/null +++ b/exercises/practice/etl/.docs/instructions.md @@ -0,0 +1,27 @@ +# Instructions + +Your task is to change the data format of letters and their point values in the game. + +Currently, letters are stored in groups based on their score, in a one-to-many mapping. + +- 1 point: "A", "E", "I", "O", "U", "L", "N", "R", "S", "T", +- 2 points: "D", "G", +- 3 points: "B", "C", "M", "P", +- 4 points: "F", "H", "V", "W", "Y", +- 5 points: "K", +- 8 points: "J", "X", +- 10 points: "Q", "Z", + +This needs to be changed to store each individual letter with its score in a one-to-one mapping. + +- "a" is worth 1 point. +- "b" is worth 3 points. +- "c" is worth 3 points. +- "d" is worth 2 points. +- etc. + +As part of this change, the team has also decided to change the letters to be lower-case rather than upper-case. + +~~~~exercism/note +If you want to look at how the data was previously structured and how it needs to change, take a look at the examples in the test suite. +~~~~ diff --git a/exercises/practice/etl/.docs/introduction.md b/exercises/practice/etl/.docs/introduction.md new file mode 100644 index 0000000..5be6514 --- /dev/null +++ b/exercises/practice/etl/.docs/introduction.md @@ -0,0 +1,16 @@ +# Introduction + +You work for a company that makes an online multiplayer game called Lexiconia. + +To play the game, each player is given 13 letters, which they must rearrange to create words. +Different letters have different point values, since it's easier to create words with some letters than others. + +The game was originally launched in English, but it is very popular, and now the company wants to expand to other languages as well. + +Different languages need to support different point values for letters. +The point values are determined by how often letters are used, compared to other letters in that language. + +For example, the letter 'C' is quite common in English, and is only worth 3 points. +But in Norwegian it's a very rare letter, and is worth 10 points. + +To make it easier to add new languages, your team needs to change the way letters and their point values are stored in the game. diff --git a/exercises/practice/etl/.meta/config.json b/exercises/practice/etl/.meta/config.json new file mode 100644 index 0000000..2a47b7f --- /dev/null +++ b/exercises/practice/etl/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "IsaacG" + ], + "files": { + "solution": [ + "etl.gd" + ], + "test": [ + "etl_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Change the data format for scoring a game to more easily add other languages.", + "source": "Based on an exercise by the JumpstartLab team for students at The Turing School of Software and Design.", + "source_url": "https://www.turing.edu/" +} diff --git a/exercises/practice/etl/.meta/example.gd b/exercises/practice/etl/.meta/example.gd new file mode 100644 index 0000000..18979ff --- /dev/null +++ b/exercises/practice/etl/.meta/example.gd @@ -0,0 +1,6 @@ +func transform(legacy: Dictionary) -> Dictionary: + var out: Dictionary[String, int] = {} + for score in legacy.keys(): + for letter in legacy[score]: + out[letter.to_lower()] = score + return out diff --git a/exercises/practice/etl/.meta/template.j2 b/exercises/practice/etl/.meta/template.j2 new file mode 100644 index 0000000..4d353cd --- /dev/null +++ b/exercises/practice/etl/.meta/template.j2 @@ -0,0 +1,11 @@ +{% for case in cases %} +func test_{{ case.func_name }}(solution_script): + var inputs = { {%- for key, val in case.given.items() %} + {{ key }}: {{ val | togdscript }},{% endfor %} + } + var expected = { {%- for key, val in case.expected.items() %} + {{ key | togdscript }}: {{ val | togdscript }},{% endfor %} + } + return [solution_script.{{ case.property | camel_to_snake }}(inputs), expected] + +{% endfor %} diff --git a/exercises/practice/etl/.meta/tests.toml b/exercises/practice/etl/.meta/tests.toml new file mode 100644 index 0000000..e937107 --- /dev/null +++ b/exercises/practice/etl/.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. + +[78a7a9f9-4490-4a47-8ee9-5a38bb47d28f] +description = "single letter" + +[60dbd000-451d-44c7-bdbb-97c73ac1f497] +description = "single score with multiple letters" + +[f5c5de0c-301f-4fdd-a0e5-df97d4214f54] +description = "multiple scores with multiple letters" + +[5db8ea89-ecb4-4dcd-902f-2b418cc87b9d] +description = "multiple scores with differing numbers of letters" diff --git a/exercises/practice/etl/etl.gd b/exercises/practice/etl/etl.gd new file mode 100644 index 0000000..2b450ba --- /dev/null +++ b/exercises/practice/etl/etl.gd @@ -0,0 +1,2 @@ +func transform(legacy: Dictionary) -> Dictionary: + pass diff --git a/exercises/practice/etl/etl_test.gd b/exercises/practice/etl/etl_test.gd new file mode 100644 index 0000000..5e05e61 --- /dev/null +++ b/exercises/practice/etl/etl_test.gd @@ -0,0 +1,77 @@ +func test_single_letter(solution_script): + var inputs = { + 1: ["A"], + } + var expected = { + "a": 1, + } + return [solution_script.transform(inputs), expected] + + +func test_single_score_with_multiple_letters(solution_script): + var inputs = { + 1: ["A", "E", "I", "O", "U"], + } + var expected = { + "a": 1, + "e": 1, + "i": 1, + "o": 1, + "u": 1, + } + return [solution_script.transform(inputs), expected] + + +func test_multiple_scores_with_multiple_letters(solution_script): + var inputs = { + 1: ["A", "E"], + 2: ["D", "G"], + } + var expected = { + "a": 1, + "d": 2, + "e": 1, + "g": 2, + } + return [solution_script.transform(inputs), expected] + + +func test_multiple_scores_with_differing_numbers_of_letters(solution_script): + var inputs = { + 1: ["A", "E", "I", "O", "U", "L", "N", "R", "S", "T"], + 2: ["D", "G"], + 3: ["B", "C", "M", "P"], + 4: ["F", "H", "V", "W", "Y"], + 5: ["K"], + 8: ["J", "X"], + 10: ["Q", "Z"], + } + var expected = { + "a": 1, + "b": 3, + "c": 3, + "d": 2, + "e": 1, + "f": 4, + "g": 2, + "h": 4, + "i": 1, + "j": 8, + "k": 5, + "l": 1, + "m": 3, + "n": 1, + "o": 1, + "p": 3, + "q": 10, + "r": 1, + "s": 1, + "t": 1, + "u": 1, + "v": 4, + "w": 4, + "x": 8, + "y": 4, + "z": 10, + } + return [solution_script.transform(inputs), expected]