Skip to content

Commit

Permalink
[gleam] complete anagram
Browse files Browse the repository at this point in the history
  • Loading branch information
joaofnds committed Apr 15, 2024
1 parent 4499c95 commit df338be
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 0 deletions.
4 changes: 4 additions & 0 deletions gleam/anagram/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.beam
*.ez
build
erl_crash.dump
32 changes: 32 additions & 0 deletions gleam/anagram/HELP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Help

## Running the tests

To run the tests, run the command `gleam test` from within the exercise directory.

## Submitting your solution

You can submit your solution using the `exercism submit src/anagram.gleam` command.
This command will upload your solution to the Exercism website and print the solution page's URL.

It's possible to submit an incomplete solution which allows you to:

- See how others have completed the exercise
- Request help from a mentor

## Need to get help?

If you'd like help solving the exercise, check the following pages:

- The [Gleam track's documentation](https://exercism.org/docs/tracks/gleam)
- The [Gleam track's programming category on the forum](https://forum.exercism.org/c/programming/gleam)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)

Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.

To get help if you're having trouble, you can use one of the following resources:

- [gleam.run](https://gleam.run/documentation/) is the gleam official documentation.
- [Discord](https://discord.gg/Fm8Pwmy) is the discord channel.
- [StackOverflow](https://stackoverflow.com/questions/tagged/gleam) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.
33 changes: 33 additions & 0 deletions gleam/anagram/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Anagram

Welcome to Anagram on Exercism's Gleam Track.
If you need help running the tests or submitting your code, check out `HELP.md`.

## 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 a set of candidate words, this exercise requests the anagram set: the subset of the candidates that are anagrams of the target.

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.

Given the target `"stone"` and candidates `"stone"`, `"tones"`, `"banana"`, `"tons"`, `"notes"`, `"Seton"`, the anagram set is `"tones"`, `"notes"`, `"Seton"`.

## Source

### Created by

- @massivefermion

### Contributed to by

- @lpil
- @kytrinyx

### Based on

Inspired by the Extreme Startup game - https://github.com/rchatley/extreme_startup
12 changes: 12 additions & 0 deletions gleam/anagram/gleam.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name = "anagram"
version = "0.1.0"

[dependencies]
gleam_bitwise = "~> 1.2"
gleam_otp = "~> 0.7 or ~> 1.0"
gleam_stdlib = "~> 0.32 or ~> 1.0"
simplifile = "~> 1.0"
gleam_erlang = ">= 0.25.0 and < 1.0.0"

[dev-dependencies]
exercism_test_runner = "~> 1.4"
27 changes: 27 additions & 0 deletions gleam/anagram/manifest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# This file was generated by Gleam
# You typically do not need to edit this file

packages = [
{ name = "argv", version = "1.0.1", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "A6E9009E50BBE863EB37D963E4315398D41A3D87D0075480FC244125808F964A" },
{ name = "exercism_test_runner", version = "1.7.0", build_tools = ["gleam"], requirements = ["argv", "gap", "glance", "gleam_community_ansi", "gleam_erlang", "gleam_json", "gleam_stdlib", "simplifile"], otp_app = "exercism_test_runner", source = "hex", outer_checksum = "2FC1BADB19BEC2AE77BFD2D3A606A014C85412A7B874CAFC4BA8CF04B0B257CD" },
{ name = "gap", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_stdlib"], otp_app = "gap", source = "hex", outer_checksum = "2EE1B0A17E85CF73A0C1D29DA315A2699117A8F549C8E8D89FA8261BE41EDEB1" },
{ name = "glance", version = "0.8.2", build_tools = ["gleam"], requirements = ["gleam_stdlib", "glexer"], otp_app = "glance", source = "hex", outer_checksum = "ACF09457E8B564AD7A0D823DAFDD326F58263C01ACB0D432A9BEFDEDD1DA8E73" },
{ name = "gleam_bitwise", version = "1.3.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_bitwise", source = "hex", outer_checksum = "B36E1D3188D7F594C7FD4F43D0D2CE17561DE896202017548578B16FE1FE9EFC" },
{ name = "gleam_community_ansi", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "FE79E08BF97009729259B6357EC058315B6FBB916FAD1C2FF9355115FEB0D3A4" },
{ name = "gleam_community_colour", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "A49A5E3AE8B637A5ACBA80ECB9B1AFE89FD3D5351FF6410A42B84F666D40D7D5" },
{ name = "gleam_erlang", version = "0.25.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "054D571A7092D2A9727B3E5D183B7507DAB0DA41556EC9133606F09C15497373" },
{ name = "gleam_json", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "8B197DD5D578EA6AC2C0D4BDC634C71A5BCA8E7DB5F47091C263ECB411A60DF3" },
{ name = "gleam_otp", version = "0.10.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "0B04FE915ACECE539B317F9652CAADBBC0F000184D586AAAF2D94C100945D72B" },
{ name = "gleam_stdlib", version = "0.36.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "C0D14D807FEC6F8A08A7C9EF8DFDE6AE5C10E40E21325B2B29365965D82EB3D4" },
{ name = "glexer", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glexer", source = "hex", outer_checksum = "4484942A465482A0A100936E1E5F12314DB4B5AC0D87575A7B9E9062090B96BE" },
{ name = "simplifile", version = "1.5.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "EB9AA8E65E5C1E3E0FDCFC81BC363FD433CB122D7D062750FFDF24DE4AC40116" },
{ name = "thoas", version = "0.4.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "4918D50026C073C4AB1388437132C77A6F6F7C8AC43C60C13758CC0ADCE2134E" },
]

[requirements]
exercism_test_runner = { version = "~> 1.4" }
gleam_bitwise = { version = "~> 1.2" }
gleam_erlang = { version = ">= 0.25.0 and < 1.0.0"}
gleam_otp = { version = "~> 0.7 or ~> 1.0" }
gleam_stdlib = { version = "~> 0.32 or ~> 1.0" }
simplifile = { version = "~> 1.0" }
18 changes: 18 additions & 0 deletions gleam/anagram/src/anagram.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import gleam/string
import gleam/list

pub fn find_anagrams(word: String, candidates: List(String)) -> List(String) {
list.filter(candidates, is_anagram(word, _))
}

fn is_anagram(a: String, b: String) -> Bool {
let a = string.lowercase(a)
let b = string.lowercase(b)
a != b && sorted_graphemes(a) == sorted_graphemes(b)
}

fn sorted_graphemes(str: String) {
str
|> string.to_graphemes
|> list.sort(string.compare)
}
89 changes: 89 additions & 0 deletions gleam/anagram/test/anagram_test.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import anagram.{find_anagrams}
import exercism/should
import exercism/test_runner

pub fn main() {
test_runner.main()
}

pub fn no_matches_test() {
find_anagrams("diaper", ["hello", "world", "zombies", "pants"])
|> should.equal([])
}

pub fn detects_two_anagrams_test() {
find_anagrams("solemn", ["lemons", "cherry", "melons"])
|> should.equal(["lemons", "melons"])
}

pub fn does_not_detect_anagram_subsets_test() {
find_anagrams("good", ["dog", "goody"])
|> should.equal([])
}

pub fn detects_anagram_test() {
find_anagrams("listen", ["enlists", "google", "inlets", "banana"])
|> should.equal(["inlets"])
}

pub fn detects_three_anagrams_test() {
find_anagrams("allergy", [
"gallery", "ballerina", "regally", "clergy", "largely", "leading",
])
|> should.equal(["gallery", "regally", "largely"])
}

pub fn detects_multiple_anagrams_with_different_case_test() {
find_anagrams("nose", ["Eons", "ONES"])
|> should.equal(["Eons", "ONES"])
}

pub fn does_not_detect_non_anagrams_with_identical_checksum_test() {
find_anagrams("mass", ["last"])
|> should.equal([])
}

pub fn detects_anagrams_case_insensitively_test() {
find_anagrams("Orchestra", ["cashregister", "Carthorse", "radishes"])
|> should.equal(["Carthorse"])
}

pub fn detects_anagrams_using_case_insensitive_subject_test() {
find_anagrams("Orchestra", ["cashregister", "carthorse", "radishes"])
|> should.equal(["carthorse"])
}

pub fn detects_anagrams_using_case_insensitive_possible_matches_test() {
find_anagrams("orchestra", ["cashregister", "Carthorse", "radishes"])
|> should.equal(["Carthorse"])
}

pub fn does_not_detect_an_anagram_if_the_original_word_is_repeated_test() {
find_anagrams("go", ["go Go GO"])
|> should.equal([])
}

pub fn anagrams_must_use_all_letters_exactly_once_test() {
find_anagrams("tapper", ["patter"])
|> should.equal([])
}

pub fn words_are_not_anagrams_of_themselves_test() {
find_anagrams("BANANA", ["BANANA"])
|> should.equal([])
}

pub fn words_are_not_anagrams_of_themselves_even_if_letter_case_is_partially_different_test() {
find_anagrams("BANANA", ["Banana"])
|> should.equal([])
}

pub fn words_are_not_anagrams_of_themselves_even_if_letter_case_is_completely_different_test() {
find_anagrams("BANANA", ["banana"])
|> should.equal([])
}

pub fn words_other_than_themselves_can_be_anagrams_test() {
find_anagrams("LISTEN", ["LISTEN", "Silent"])
|> should.equal(["Silent"])
}

0 comments on commit df338be

Please sign in to comment.