# dscottboggs's solution

## to Anagram in the Crystal Track

Published at Feb 15 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"`.

## Setup

Follow the setup instructions for Crystal here:

http://exercism.io/languages/crystal

More help installing can be found here:

http://crystal-lang.org/docs/installation/index.html

## Making the Test Suite Pass

Execute the tests with:

``````\$ crystal spec
``````

In each test suite all but the first test have been skipped.

Once you get a test passing, you can unskip the next one by changing `pending` to `it`.

## Source

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

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### anagram_spec.cr

``````require "spec"
require "../src/*"

describe "Anagram" do
it "no matches" do
Anagram.find("diaper", ["hello", "world", "zombies", "pants"]).should eq [] of String
end

pending "detects two anagrams" do
Anagram.find("master", ["stream", "pigeon", "maters"]).should eq ["stream", "maters"]
end

pending "does not detect anagram subsets" do
Anagram.find("good", ["dog", "goody"]).should eq [] of String
end

pending "detects anagram" do
Anagram.find("listen", ["enlists", "google", "inlets", "banana"]).should eq ["inlets"]
end

pending "detects three anagrams" do
Anagram.find("allergy", ["gallery", "ballerina", "regally", "clergy", "largely", "leading"]).should eq ["gallery", "regally", "largely"]
end

pending "does not detect non-anagrams with identical checksum" do
Anagram.find("mass", ["last"]).should eq [] of String
end

pending "detects anagrams case-insensitively" do
Anagram.find("Orchestra", ["cashregister", "Carthorse", "radishes"]).should eq ["Carthorse"]
end

pending "detects anagrams using case-insensitive subject" do
Anagram.find("Orchestra", ["cashregister", "carthorse", "radishes"]).should eq ["carthorse"]
end

pending "detects anagrams using case-insensitive possible matches" do
Anagram.find("orchestra", ["cashregister", "Carthorse", "radishes"]).should eq ["Carthorse"]
end

pending "does not detect an anagram if the original word is repeated" do
Anagram.find("go", ["go Go GO"]).should eq [] of String
end

pending "anagrams must use all letters exactly once" do
Anagram.find("tapper", ["patter"]).should eq [] of String
end

pending "words are not anagrams of themselves (case-insensitive)" do
Anagram.find("BANANA", ["BANANA", "Banana", "banana"]).should eq [] of String
end
end``````
``````module Anagram
struct Checker
property word : String

getter counts = {} of Char => Int32

def initialize(word)
(@word = word.downcase).each_char do |char|
counts[char] = counts.fetch(char, default: 0) + 1
end
end

delegate size, to: @word

def anagram?(of possible_anagram)
return false if size != possible_anagram.size
possible_anagram = possible_anagram.downcase
return false if possible_anagram == word
their_letter_counts = {} of Char => Int32
possible_anagram.each_char do |char|
their_letter_counts[char] = their_letter_counts.fetch(char, default: 0) + 1
end
counts == their_letter_counts
end

def check(possible_anagrams : Array(String))
possible_anagrams.select { |word| anagram? of: word }
end
end

def self.find(word, possible_anagrams : Array(String))
Checker.new(word).check possible_anagrams
end
end``````