From dd7165490d58e82b14e103fdd30a00cc18529655 Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Fri, 25 Sep 2026 22:41:35 -0700 Subject: [PATCH] [anagram] Sync files and add a test generator --- .../practice/anagram/.docs/instructions.md | 15 +- .../practice/anagram/.docs/introduction.md | 12 ++ exercises/practice/anagram/.meta/config.json | 2 +- exercises/practice/anagram/.meta/template.j2 | 9 + exercises/practice/anagram/anagram_test.gd | 162 ++++++++++-------- 5 files changed, 122 insertions(+), 78 deletions(-) create mode 100644 exercises/practice/anagram/.docs/introduction.md create mode 100644 exercises/practice/anagram/.meta/template.j2 diff --git a/exercises/practice/anagram/.docs/instructions.md b/exercises/practice/anagram/.docs/instructions.md index 7d1c828..dca24f5 100644 --- a/exercises/practice/anagram/.docs/instructions.md +++ b/exercises/practice/anagram/.docs/instructions.md @@ -1,13 +1,12 @@ # Instructions -An anagram is a rearrangement of letters to form a new word: for example `"owns"` is an anagram of `"snow"`. -A word is not its own anagram: for example, `"stop"` is not an anagram of `"stop"`. +Given a target word and one or more candidate words, your task is to find the candidates that are anagrams of the target. -Given a target word and a set of candidate words, this exercise requests the anagram set: the subset of the candidates that are anagrams of the target. +An anagram is a rearrangement of letters to form a new word: for example `"owns"` is an anagram of `"snow"`. +A word is _not_ its own anagram: for example, `"stop"` is not an anagram of `"stop"`. -The target and candidates are words of one or more ASCII alphabetic characters (`A`-`Z` and `a`-`z`). -Lowercase and uppercase characters are equivalent: for example, `"PoTS"` is an anagram of `"sTOp"`, but `StoP` is not an anagram of `sTOp`. -The anagram set is the subset of the candidate set that are anagrams of the target (in any order). -Words in the anagram set should have the same letter case as in the candidate set. +The target word and candidate words are made up of one or more ASCII alphabetic characters (`A`-`Z` and `a`-`z`). +Lowercase and uppercase characters are equivalent: for example, `"PoTS"` is an anagram of `"sTOp"`, but `"StoP"` is not an anagram of `"sTOp"`. +The words you need to find should be taken from the candidate words, using the same letter case. -Given the target `"stone"` and candidates `"stone"`, `"tones"`, `"banana"`, `"tons"`, `"notes"`, `"Seton"`, the anagram set is `"tones"`, `"notes"`, `"Seton"`. +Given the target `"stone"` and the candidate words `"stone"`, `"tones"`, `"banana"`, `"tons"`, `"notes"`, and `"Seton"`, the anagram words you need to find are `"tones"`, `"notes"`, and `"Seton"`. diff --git a/exercises/practice/anagram/.docs/introduction.md b/exercises/practice/anagram/.docs/introduction.md new file mode 100644 index 0000000..1acbdf0 --- /dev/null +++ b/exercises/practice/anagram/.docs/introduction.md @@ -0,0 +1,12 @@ +# Introduction + +At a garage sale, you find a lovely vintage typewriter at a bargain price! +Excitedly, you rush home, insert a sheet of paper, and start typing away. +However, your excitement wanes when you examine the output: all words are garbled! +For example, it prints "stop" instead of "post" and "least" instead of "stale." +Carefully, you try again, but now it prints "spot" and "slate." +After some experimentation, you find there is a random delay before each letter is printed, which messes up the order. +You now understand why they sold it for so little money! + +You realize this quirk allows you to generate anagrams, which are words formed by rearranging the letters of another word. +Pleased with your finding, you spend the rest of the day generating hundreds of anagrams. diff --git a/exercises/practice/anagram/.meta/config.json b/exercises/practice/anagram/.meta/config.json index 7aa4fe4..0d7fcf2 100644 --- a/exercises/practice/anagram/.meta/config.json +++ b/exercises/practice/anagram/.meta/config.json @@ -13,7 +13,7 @@ ".meta/example.gd" ] }, - "blurb": "Given a word and a list of possible anagrams, select the correct sublist.", + "blurb": "Find the words that use the same letters as another word.", "source": "Inspired by the Extreme Startup game", "source_url": "https://github.com/rchatley/extreme_startup" } diff --git a/exercises/practice/anagram/.meta/template.j2 b/exercises/practice/anagram/.meta/template.j2 new file mode 100644 index 0000000..8561c0d --- /dev/null +++ b/exercises/practice/anagram/.meta/template.j2 @@ -0,0 +1,9 @@ +{% for case in cases %} +func test_{{ case["func_name"] }}(solution_script): + var subject = "{{ case["input"]["subject"] }}" + var candidates = {{ case["input"]["candidates"] }} + var want = {{ case["expected"] }} + var got = solution_script.find_anagram(subject, candidates) + return [got, want] + +{% endfor %} diff --git a/exercises/practice/anagram/anagram_test.gd b/exercises/practice/anagram/anagram_test.gd index 8e69454..b94f976 100644 --- a/exercises/practice/anagram/anagram_test.gd +++ b/exercises/practice/anagram/anagram_test.gd @@ -1,118 +1,142 @@ func test_no_matches(solution_script): - var subject = "diaper" - var candidates = ["hello", "world", "zombies", "pants"] - var expected = [] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "diaper" + var candidates = ['hello', 'world', 'zombies', 'pants'] + var want = [] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_detects_two_anagrams(solution_script): - var subject = "solemn" - var candidates = ["lemons", "cherry", "melons"] - var expected = ["lemons", "melons"] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "solemn" + var candidates = ['lemons', 'cherry', 'melons'] + var want = ['lemons', 'melons'] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_does_not_detect_anagram_subsets(solution_script): - var subject = "listen" - var candidates = ["enlists", "google", "inlets", "banana"] - var expected = ["inlets"] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "good" + var candidates = ['dog', 'goody'] + var want = [] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] + + +func test_detects_anagram(solution_script): + var subject = "listen" + var candidates = ['enlists', 'google', 'inlets', 'banana'] + var want = ['inlets'] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_detects_three_anagrams(solution_script): - var subject = "allergy" - var candidates = ["gallery", "ballerina", "regally", "clergy", "largely", "leading"] - var expected = ["gallery", "regally", "largely"] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "allergy" + var candidates = ['gallery', 'ballerina', 'regally', 'clergy', 'largely', 'leading'] + var want = ['gallery', 'regally', 'largely'] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_detects_multiple_anagrams_with_different_case(solution_script): - var subject = "nose" - var candidates = ["Eons", "ONES"] - var expected = ["Eons", "ONES"] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "nose" + var candidates = ['Eons', 'ONES'] + var want = ['Eons', 'ONES'] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_does_not_detect_non_anagrams_with_identical_checksum(solution_script): - var subject = "mass" - var candidates = ["last"] - var expected = [] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "mass" + var candidates = ['last'] + var want = [] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_detects_anagrams_case_insensitively(solution_script): - var subject = "Orchestra" - var candidates = ["cashregister", "Carthorse", "radishes"] - var expected = ["Carthorse"] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "Orchestra" + var candidates = ['cashregister', 'Carthorse', 'radishes'] + var want = ['Carthorse'] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_detects_anagrams_using_case_insensitive_subject(solution_script): - var subject = "Orchestra" - var candidates = ["cashregister", "carthorse", "radishes"] - var expected = ["carthorse"] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "Orchestra" + var candidates = ['cashregister', 'carthorse', 'radishes'] + var want = ['carthorse'] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_detects_anagrams_using_case_insensitive_possible_matches(solution_script): - var subject = "orchestra" - var candidates = ["cashregister", "Carthorse", "radishes"] - var expected = ["Carthorse"] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "orchestra" + var candidates = ['cashregister', 'Carthorse', 'radishes'] + var want = ['Carthorse'] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_does_not_detect_an_anagram_if_the_original_word_is_repeated(solution_script): - var subject = "go" - var candidates = ["goGoGO"] - var expected = [] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "go" + var candidates = ['goGoGO'] + var want = [] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_anagrams_must_use_all_letters_exactly_once(solution_script): - var subject = "tapper" - var candidates = ["patter"] - var expected = [] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "tapper" + var candidates = ['patter'] + var want = [] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_words_are_not_anagrams_of_themselves(solution_script): - var subject = "BANANA" - var candidates = ["BANANA"] - var expected = [] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "BANANA" + var candidates = ['BANANA'] + var want = [] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_words_are_not_anagrams_of_themselves_even_if_letter_case_is_partially_different(solution_script): - var subject = "BANANA" - var candidates = ["Banana"] - var expected = [] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "BANANA" + var candidates = ['Banana'] + var want = [] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_words_are_not_anagrams_of_themselves_even_if_letter_case_is_completely_different(solution_script): - var subject = "BANANA" - var candidates = ["banana"] - var expected = [] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "BANANA" + var candidates = ['banana'] + var want = [] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_words_other_than_themselves_can_be_anagrams(solution_script): - var subject = "LISTEN" - var candidates = ["LISTEN", "Silent"] - var expected = ["Silent"] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "LISTEN" + var candidates = ['LISTEN', 'Silent'] + var want = ['Silent'] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_handles_case_of_greek_letters(solution_script): - var subject = "ΑΒΓ" - var candidates = ["ΒΓΑ", "ΒΓΔ", "γβα", "αβγ"] - var expected = ["ΒΓΑ", "γβα"] - return [solution_script.find_anagram(subject, candidates), expected] + var subject = "ΑΒΓ" + var candidates = ['ΒΓΑ', 'ΒΓΔ', 'γβα', 'αβγ'] + var want = ['ΒΓΑ', 'γβα'] + var got = solution_script.find_anagram(subject, candidates) + return [got, want] func test_different_characters_may_have_the_same_bytes(solution_script): - var subject = "a⬂" - var candidates = ["€a"] - var expected = [] - return [solution_script.find_anagram(subject, candidates), expected] - + var subject = "a⬂" + var candidates = ['€a'] + var want = [] + var got = solution_script.find_anagram(subject, candidates) + return [got, want]