ðŸŽ‰ Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io ðŸŽ‰

# otaviopace's solution

## to Anagram in the ReasonML Track

Published at Dec 25 2020 · 0 comments
Instructions
Test suite
Solution

An anagram is a rearrangement of letters to form a new word. Given a word and a list of candidates, select the sublist of anagrams of the given word.

Given `"listen"` and a list of candidates like `"enlists" "google" "inlets" "banana"` the program should return a list containing `"inlets"`.

## Source

Inspired by the Extreme Startup game https://github.com/rchatley/extreme_startup

## Building and testing

You will need the node package manager (npm) installed - download from here There is one time setup for each exercise, which may take a few minutes:

``````npm install
``````

Open two shells, and in the first, start the build process.

``````npm start
``````

In the second, start the tests running.

``````npm test
``````

As you edit the code, the two processes will continually rebuild and rerun the tests.

### Anagram_test.re

``````open Jest;
open Expect;
open Anagram;

describe("Anagram", () => {
test("no matches", () =>
expect(anagrams("diaper", ["hello", "world", "zombies", "pants"])) |> toEqual([])
);
test("detects two anagrams", () =>
expect(anagrams("master", ["stream", "pigeon", "maters"])) |> toEqual(["stream", "maters"])
);
test("does not detect anagram subsets", () =>
expect(anagrams("good", ["dog", "goody"]))  |> toEqual([])
);
test("detects anagram", () =>
expect(anagrams("listen", ["enlists", "google", "inlets", "banana"]))  |> toEqual(["inlets"])
);
test("detects three anagrams", () =>
expect(anagrams("allergy", ["gallery", "ballerina", "regally", "clergy", "largely", "leading"]))  |> toEqual(["gallery", "regally", "largely"])
);
test("detects multiple anagrams with different case", () =>
expect(anagrams("nose", ["Eons", "ONES"]))  |> toEqual(["Eons", "ONES"])
);
test("does not detect non-anagrams with identical checksum", () =>
expect(anagrams("mass", ["last"]))  |> toEqual([])
);
test("detects anagrams case-insensitively", () =>
expect(anagrams("Orchestra", ["cashregister", "Carthorse", "radishes"]))  |> toEqual(["Carthorse"])
);
test("detects anagrams using case-insensitive subject", () =>
expect(anagrams("Orchestra", ["cashregister", "carthorse", "radishes"])) |> toEqual(["carthorse"])
);
test("detects anagrams using case-insensitive possible matches", () =>
expect(anagrams("orchestra", ["cashregister", "Carthorse", "radishes"])) |> toEqual(["Carthorse"])
);
test("does not detect a anagram if the original word is repeated", () =>
expect(anagrams("go", ["go Go GO"])) |> toEqual([])
);
test("anagrams must use all letters exactly once", () =>
expect(anagrams("tapper", ["patter"])) |> toEqual([])
);
test("words are not anagrams of themselves (case-insensitive)", () =>
expect(anagrams("BANANA", ["BANANA", "Banana", "banana"])) |> toEqual([])
);
test("words other than themselves can be anagrams", () =>
expect(anagrams("LISTEN", ["Listen", "Silent", "LISTEN"])) |> toEqual(["Silent"])
);
})``````
``````let areSameLength = (a, b) => Js.String.length(a) !== Js.String.length(b);

let equal = (a, b) => compare(a, b) === 0;

let anagrams = (input, words) => {
let lowerCaseInput = Js.String.toLowerCase(input);
let inputChars = Js.String.split("", lowerCaseInput);

Array.sort(compare, inputChars);

Belt.List.keep(
words,
(word) => {
if (areSameLength(input, word)) {
false
} else {
let lowerCaseWord = Js.String.toLowerCase(word);
if (equal(lowerCaseInput, lowerCaseWord)) {
false
} else {
let wordChars = Js.String.split("", lowerCaseWord);

Array.sort(compare, wordChars);

equal(inputChars, wordChars)
}
}
}
)
};``````