Skip to content

Commit

Permalink
Add exercise: anagram (JuliaLang#17)
Browse files Browse the repository at this point in the history
* Add exercise: anagram

* Anagram exercise: use AbstractString as suggested

* Fix exercise anagram template file: use AbstractString
  • Loading branch information
andrej-makarov-skrt authored and SaschaMann committed Jan 26, 2017
1 parent f682d4d commit 34ba97c
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 1 deletion.
13 changes: 12 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,25 @@
"active": false,
"test_pattern": "TODO",
"exercises": [
{
{
"slug": "leap",
"difficulty": 1,
"topics": [
"control-flow (conditionals)",
"integers",
"mathematics"
]
},
{
"slug": "anagram",
"difficulty": 2,
"topics": [
"control-flow (loops)",
"arrays",
"strings",
"sorting",
"filtering"
]
}
],
"deprecated": [
Expand Down
4 changes: 4 additions & 0 deletions exercises/anagram/anagram.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
function detect_anagrams(subject::AbstractString, candidates::AbstractArray)

end

43 changes: 43 additions & 0 deletions exercises/anagram/example.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Anagrams are two or more words that composed of the same characters but in a different order

function is_anagram(s1::AbstractString, s2::AbstractString)
# Disable case sensitivity
s1 = lowercase(s1)
s2 = lowercase(s2)

# Similar and different-length strings are not anagrams
if length(s1) != length(s2) || s1 == s2
return false
end

# Calculate count of every character in the first string
chr_count = Dict()
for c in s1
chr_count[c] = get(chr_count, c, 0) + 1
end

# Reduce the count by every character from the second string
for c in s2
t = get(chr_count, c, 0) - 1
if t < 0
# Got character that not exist in the first string
return false
else
chr_count[c] = t
end
end

# Check all counts to be zeroes
return all(i->(i==0), values(chr_count))
end

function detect_anagrams(subject::AbstractString, candidates::AbstractArray)
result = []
for candidate = candidates
if is_anagram(subject, candidate)
push!(result, candidate)
end
end
result
end

68 changes: 68 additions & 0 deletions exercises/anagram/runtests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using Base.Test

include("anagram.jl")

@testset "no matches" begin
@test detect_anagrams("diasper", ["hello", "world", "zombies", "pants"]) == []
end

@testset "detects simple anagram" begin
@test detect_anagrams("ant", ["tan", "stand", "at"]) == ["tan"]
end

@testset "does not detect false positives" begin
@test detect_anagrams("galea", ["eagle"]) == []
end

@testset "detects multiple anagrams" begin
@test detect_anagrams("master", ["stream", "pigeon", "maters"]) == ["stream", "maters"]
end

@testset "does not detect anagram subsets" begin
@test detect_anagrams("good", ["dog", "goody"]) == []
end

@testset "detects anagram" begin
@test detect_anagrams("listen", ["enlists", "google", "inlets", "banana"]) == ["inlets"]
end

@testset "detects multiple anagrams" begin
@test detect_anagrams("allergy", ["gallery", "ballerina", "regally", "clergy", "largely", "leading"]) == ["gallery", "regally", "largely"]
end

@testset "does not detect identical words" begin
@test detect_anagrams("corn", ["corn", "dark", "Corn", "rank", "CORN", "cron", "park"]) == ["cron"]
end

@testset "does not detect non-anagrams with identical checksum" begin
@test detect_anagrams("mass", ["last"]) == []
end

@testset "detects anagrams case-insensitively" begin
@test detect_anagrams("Orchestra", ["cashregister", "Carthorse", "radishes"]) == ["Carthorse"]
end

@testset "detects anagrams using case-insensitive subject" begin
@test detect_anagrams("Orchestra", ["cashregister", "carthorse", "radishes"]) == ["carthorse"]
end

@testset "detects anagrams using case-insensitive possible matches" begin
@test detect_anagrams("orchestra", ["cashregister", "Carthorse", "radishes"]) == ["Carthorse"]
end

@testset "does not detect a word as its own anagram" begin
@test detect_anagrams("banana", ["Banana"]) == []
end

@testset "does not detect a anagram if the original word is repeated" begin
@test detect_anagrams("go", ["go Go GO"]) == []
end

@testset "anagrams must use all letters exactly once" begin
@test detect_anagrams("tapper", ["patter"]) == []
end

@testset "capital word is not own anagram" begin
@test detect_anagrams("BANANA", ["Banana"]) == []
end

0 comments on commit 34ba97c

Please sign in to comment.