Run pre Elm 0.17 exercises through elm-format version 0.3.0-alpha

This commit is contained in:
Erik Simmler 2016-06-19 17:46:13 -04:00
parent 65db27e7e0
commit 91aaf056a1
49 changed files with 1178 additions and 1469 deletions

View file

@ -3,4 +3,4 @@ module Accumulate exposing (..)
accumulate : (a -> b) -> List a -> List b accumulate : (a -> b) -> List a -> List b
accumulate func input = accumulate func input =
List.foldr (\v c -> func v :: c) [] input List.foldr (\v c -> func v :: c) [] input

View file

@ -7,28 +7,23 @@ import String
square : Int -> Int square : Int -> Int
square x = square x =
x * x x * x
tests : Test tests : Test
tests = tests =
suite suite "Accumulate"
"Accumulate" [ test "[]] Accumulate"
[ test (assertEqual [] (accumulate square []))
"[]] Accumulate" , test "square Accumulate"
(assertEqual [] (accumulate square [])) (assertEqual [ 1, 4, 9 ] (accumulate square [ 1, 2, 3 ]))
, test , test "toUpper Accumulate"
"square Accumulate" (assertEqual [ "HELLO", "WORLD" ] (accumulate String.toUpper [ "hello", "world" ]))
(assertEqual [ 1, 4, 9 ] (accumulate square [ 1, 2, 3 ])) , test "reverse Accumulate"
, test (assertEqual [ "olleh", "dlrow" ] (accumulate String.reverse [ "hello", "world" ]))
"toUpper Accumulate" ]
(assertEqual [ "HELLO", "WORLD" ] (accumulate String.toUpper [ "hello", "world" ]))
, test
"reverse Accumulate"
(assertEqual [ "olleh", "dlrow" ] (accumulate String.reverse [ "hello", "world" ]))
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -6,25 +6,25 @@ import Bitwise
isAllergicTo : String -> Int -> Bool isAllergicTo : String -> Int -> Bool
isAllergicTo name score = isAllergicTo name score =
List.member name (toList score) List.member name (toList score)
toList : Int -> List String toList : Int -> List String
toList score = toList score =
allergies allergies
|> List.indexedMap (\i n -> ( Bitwise.shiftLeft 1 i, n )) |> List.indexedMap (\i n -> ( Bitwise.shiftLeft 1 i, n ))
|> List.filter (\( s, n ) -> Bitwise.and s score > 0) |> List.filter (\( s, n ) -> Bitwise.and s score > 0)
|> List.map snd |> List.map snd
allergies : List String allergies : List String
allergies = allergies =
[ "eggs" [ "eggs"
, "peanuts" , "peanuts"
, "shellfish" , "shellfish"
, "strawberries" , "strawberries"
, "tomatoes" , "tomatoes"
, "chocolate" , "chocolate"
, "pollen" , "pollen"
, "cats" , "cats"
] ]

View file

@ -7,65 +7,46 @@ import List
tests : Test tests : Test
tests = tests =
suite suite "Allergies"
"Allergies" [ suite "isAllergicTo"
[ suite [ suite "no allergies means not allergic"
"isAllergicTo" [ test "peanuts"
[ suite (assert (not (isAllergicTo "peanuts" 0)))
"no allergies means not allergic" , test "cats"
[ test (assert (not (isAllergicTo "cats" 0)))
"peanuts" , test "strawberries"
(assert (not (isAllergicTo "peanuts" 0))) (assert (not (isAllergicTo "strawberries" 0)))
, test ]
"cats" , test "is allergic to eggs"
(assert (not (isAllergicTo "cats" 0))) (assert (isAllergicTo "eggs" 1))
, test , suite "has the right allergies"
"strawberries" [ test "eggs"
(assert (not (isAllergicTo "strawberries" 0))) (assert (isAllergicTo "eggs" 5))
, test "shellfish"
(assert (isAllergicTo "shellfish" 5))
, test "strawberries"
(assert (not (isAllergicTo "strawberries" 5)))
]
] ]
, test , suite "toList"
"is allergic to eggs" [ test "no allergies at all"
(assert (isAllergicTo "eggs" 1)) (assertEqual [] (toList (0)))
, suite , test "allergic to just peanuts"
"has the right allergies" (assertEqual [ "peanuts" ] (toList (2)))
[ test , test "allergic to everything"
"eggs" (assertEqual (List.sort [ "eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats" ])
(assert (isAllergicTo "eggs" 5)) (255 |> toList |> List.sort)
, test )
"shellfish" , test "ignore non allergen score parts"
(assert (isAllergicTo "shellfish" 5)) (assertEqual [ "eggs" ] (toList 257))
, test , test "ignore non allergen score parts"
"strawberries" (assertEqual (List.sort [ "eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats" ])
(assert (not (isAllergicTo "strawberries" 5))) (509 |> toList |> List.sort)
)
] ]
] ]
, suite
"toList"
[ test
"no allergies at all"
(assertEqual [] (toList (0)))
, test
"allergic to just peanuts"
(assertEqual [ "peanuts" ] (toList (2)))
, test
"allergic to everything"
(assertEqual
(List.sort [ "eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats" ])
(255 |> toList |> List.sort)
)
, test
"ignore non allergen score parts"
(assertEqual [ "eggs" ] (toList 257))
, test
"ignore non allergen score parts"
(assertEqual
(List.sort [ "eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats" ])
(509 |> toList |> List.sort)
)
]
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -5,16 +5,16 @@ import String exposing (toLower, toList)
detect : String -> List String -> List String detect : String -> List String -> List String
detect word candidates = detect word candidates =
let let
original = original =
toLower word toLower word
ref = ref =
normalize word normalize word
in in
List.filter (\w -> normalize w == ref && toLower w /= original) candidates List.filter (\w -> normalize w == ref && toLower w /= original) candidates
normalize : String -> List Char normalize : String -> List Char
normalize word = normalize word =
word |> toLower |> toList |> List.sort word |> toLower |> toList |> List.sort

View file

@ -6,131 +6,90 @@ import Anagram exposing (detect)
tests : Test tests : Test
tests = tests =
suite suite "Anagram"
"Anagram" [ test "no matches"
[ test (assertEqual []
"no matches" (detect "diaper" [ "hello", "world", "zombies", "pants" ])
(assertEqual )
[] , test "detects simple anagram"
(detect "diaper" [ "hello", "world", "zombies", "pants" ]) (assertEqual [ "tan" ]
) (detect "ant" [ "tan", "stand", "at" ])
, test )
"detects simple anagram" , test "does not detect false positives"
(assertEqual (assertEqual []
[ "tan" ] (detect "galea" [ "eagle" ])
(detect "ant" [ "tan", "stand", "at" ]) )
) , test "detects multiple anagrams"
, test (assertEqual [ "stream", "maters" ]
"does not detect false positives" (detect "master" [ "stream", "pigeon", "maters" ])
(assertEqual )
[] , test "does not detect anagram subsets"
(detect "galea" [ "eagle" ]) (assertEqual []
) (detect "good" [ "dog", "goody" ])
, test )
"detects multiple anagrams" , test "detects anagram"
(assertEqual (assertEqual [ "inlets" ]
[ "stream", "maters" ] (detect "listen" [ "enlists", "google", "inlets", "banana" ])
(detect "master" [ "stream", "pigeon", "maters" ]) )
) , test "detects multiple anagrams"
, test (assertEqual [ "gallery", "regally", "largely" ]
"does not detect anagram subsets" (detect "allergy" [ "gallery", "ballerina", "regally", "clergy", "largely", "leading" ])
(assertEqual )
[] , test "does not detect indentical words"
(detect "good" [ "dog", "goody" ]) (assertEqual [ "cron" ]
) (detect "corn" [ "corn", "dark", "Corn", "rank", "CORN", "cron", "park" ])
, test )
"detects anagram" , test "does not detect non-anagrams with identical checksum"
(assertEqual (assertEqual []
[ "inlets" ] (detect "mass" [ "last" ])
(detect "listen" [ "enlists", "google", "inlets", "banana" ]) )
) , test "detects anagrams case-insensitively"
, test (assertEqual [ "Carthorse" ]
"detects multiple anagrams" (detect "Orchestra" [ "cashregister", "Carthorse", "radishes" ])
(assertEqual )
[ "gallery", "regally", "largely" ] , test "detects anagrams using case-insensitive subject"
(detect "allergy" [ "gallery", "ballerina", "regally", "clergy", "largely", "leading" ]) (assertEqual [ "carthorse" ]
) (detect "Orchestra" [ "cashregister", "carthorse", "radishes" ])
, test )
"does not detect indentical words" , test "detects anagrams using case-insensitve possible matches"
(assertEqual (assertEqual [ "Carthorse" ]
[ "cron" ] (detect "orchestra" [ "cashregister", "Carthorse", "radishes" ])
(detect "corn" [ "corn", "dark", "Corn", "rank", "CORN", "cron", "park" ]) )
) , test "does not detect a word as its own anagram"
, test (assertEqual []
"does not detect non-anagrams with identical checksum" (detect "banana" [ "Banana" ])
(assertEqual )
[] , test "does not detect a anagram if the original word is repeated"
(detect "mass" [ "last" ]) (assertEqual []
) (detect "go" [ "go Go GO" ])
, test )
"detects anagrams case-insensitively" , test "anagrams must use all letters exactly once"
(assertEqual (assertEqual []
[ "Carthorse" ] (detect "tapper" [ "patter" ])
(detect "Orchestra" [ "cashregister", "Carthorse", "radishes" ]) )
) , test "eliminates anagrams with the same checksum"
, test (assertEqual []
"detects anagrams using case-insensitive subject" (detect "mass" [ "last" ])
(assertEqual )
[ "carthorse" ] , test "detects unicode anagrams"
(detect "Orchestra" [ "cashregister", "carthorse", "radishes" ]) (assertEqual [ "ΒΓΑ", "γβα" ]
) (detect "ΑΒΓ" [ "ΒΓΑ", "ΒΓΔ", "γβα" ])
, test )
"detects anagrams using case-insensitve possible matches" , test "eliminates misleading unicode anagrams"
(assertEqual (assertEqual []
[ "Carthorse" ] (detect "ΑΒΓ" [ "ABΓ" ])
(detect "orchestra" [ "cashregister", "Carthorse", "radishes" ]) )
) , test "capital word is not own anagram"
, test (assertEqual []
"does not detect a word as its own anagram" (detect "BANANA" [ "Banana" ])
(assertEqual )
[] , test "anagrams must use all letters exactly once"
(detect "banana" [ "Banana" ]) (assertEqual []
) (detect "patter" [ "tapper" ])
, test )
"does not detect a anagram if the original word is repeated" ]
(assertEqual
[]
(detect "go" [ "go Go GO" ])
)
, test
"anagrams must use all letters exactly once"
(assertEqual
[]
(detect "tapper" [ "patter" ])
)
, test
"eliminates anagrams with the same checksum"
(assertEqual
[]
(detect "mass" [ "last" ])
)
, test
"detects unicode anagrams"
(assertEqual
[ "ΒΓΑ", "γβα" ]
(detect "ΑΒΓ" [ "ΒΓΑ", "ΒΓΔ", "γβα" ])
)
, test
"eliminates misleading unicode anagrams"
(assertEqual
[]
(detect "ΑΒΓ" [ "ABΓ" ])
)
, test
"capital word is not own anagram"
(assertEqual
[]
(detect "BANANA" [ "Banana" ])
)
, test
"anagrams must use all letters exactly once"
(assertEqual
[]
(detect "patter" [ "tapper" ])
)
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -6,41 +6,41 @@ import Regex
hey : String -> String hey : String -> String
hey remark = hey remark =
if isShouting remark then if isShouting remark then
"Whoa, chill out!" "Whoa, chill out!"
else if isQuestion remark then else if isQuestion remark then
"Sure." "Sure."
else if isSilence remark then else if isSilence remark then
"Fine. Be that way!" "Fine. Be that way!"
else else
"Whatever." "Whatever."
isShouting : String -> Bool isShouting : String -> Bool
isShouting remark = isShouting remark =
isUppercase remark && hasCharacters remark isUppercase remark && hasCharacters remark
isUppercase : String -> Bool isUppercase : String -> Bool
isUppercase remark = isUppercase remark =
remark == String.toUpper remark remark == String.toUpper remark
isQuestion : String -> Bool isQuestion : String -> Bool
isQuestion remark = isQuestion remark =
String.endsWith "?" remark String.endsWith "?" remark
hasCharacters : String -> Bool hasCharacters : String -> Bool
hasCharacters remark = hasCharacters remark =
Regex.contains characterRegex remark Regex.contains characterRegex remark
characterRegex : Regex.Regex characterRegex : Regex.Regex
characterRegex = characterRegex =
Regex.regex "[a-zA-Z]" Regex.regex "[a-zA-Z]"
isSilence : String -> Bool isSilence : String -> Bool
isSilence remark = isSilence remark =
String.isEmpty (String.trim remark) String.isEmpty (String.trim remark)

View file

@ -9,66 +9,65 @@ import Bob
tests : Test tests : Test
tests = tests =
suite suite "Bob"
"Bob" [ test "stating something" (assertEqual "Whatever." (Bob.hey "Tom-ay-to, tom-aaaah-to."))
[ test "stating something" (assertEqual "Whatever." (Bob.hey "Tom-ay-to, tom-aaaah-to.")) , test "shouting" (assertEqual "Whoa, chill out!" (Bob.hey "WATCH OUT!"))
, test "shouting" (assertEqual "Whoa, chill out!" (Bob.hey "WATCH OUT!")) , test "shouting gibberish" (assertEqual "Whoa, chill out!" (Bob.hey (uppercaseGibberish 10)))
, test "shouting gibberish" (assertEqual "Whoa, chill out!" (Bob.hey (uppercaseGibberish 10))) , test "asking a question" (assertEqual "Sure." (Bob.hey "Does this cryogenic chamber make me look fat?"))
, test "asking a question" (assertEqual "Sure." (Bob.hey "Does this cryogenic chamber make me look fat?")) , test "asking a numeric question" (assertEqual "Sure." (Bob.hey "You are, what, like 15?"))
, test "asking a numeric question" (assertEqual "Sure." (Bob.hey "You are, what, like 15?")) , test "asking gibberish" (assertEqual "Sure." (Bob.hey (gibberishQuestion 20)))
, test "asking gibberish" (assertEqual "Sure." (Bob.hey (gibberishQuestion 20))) , test "talking forcefully" (assertEqual "Whatever." (Bob.hey "Let's go make out behind the gym!"))
, test "talking forcefully" (assertEqual "Whatever." (Bob.hey "Let's go make out behind the gym!")) , test "using acronyms in regular speech" (assertEqual "Whatever." (Bob.hey "It's OK if you don't want to go to the DMV."))
, test "using acronyms in regular speech" (assertEqual "Whatever." (Bob.hey "It's OK if you don't want to go to the DMV.")) , test "forceful questions" (assertEqual "Whoa, chill out!" (Bob.hey "WHAT THE HELL WERE YOU THINKING?"))
, test "forceful questions" (assertEqual "Whoa, chill out!" (Bob.hey "WHAT THE HELL WERE YOU THINKING?")) , test "shouting numbers" (assertEqual "Whoa, chill out!" (Bob.hey "1, 2, 3 GO!"))
, test "shouting numbers" (assertEqual "Whoa, chill out!" (Bob.hey "1, 2, 3 GO!")) , test "only numbers" (assertEqual "Whatever." (Bob.hey "1, 2, 3"))
, test "only numbers" (assertEqual "Whatever." (Bob.hey "1, 2, 3")) , test "question with only numbers" (assertEqual "Sure." (Bob.hey "4?"))
, test "question with only numbers" (assertEqual "Sure." (Bob.hey "4?")) , test "shouting with special characters" (assertEqual "Whoa, chill out!" (Bob.hey "ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!)"))
, test "shouting with special characters" (assertEqual "Whoa, chill out!" (Bob.hey "ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!)")) , test "shouting with no exclamation mark" (assertEqual "Whoa, chill out!" (Bob.hey "I HATE YOU"))
, test "shouting with no exclamation mark" (assertEqual "Whoa, chill out!" (Bob.hey "I HATE YOU")) , test "statement containing a question mark" (assertEqual "Whatever." (Bob.hey "Ending with ? means a question."))
, test "statement containing a question mark" (assertEqual "Whatever." (Bob.hey "Ending with ? means a question.")) , test "prattling on" (assertEqual "Sure." (Bob.hey "Wait! Hang on. Are you going to be OK?"))
, test "prattling on" (assertEqual "Sure." (Bob.hey "Wait! Hang on. Are you going to be OK?")) , test "silence" (assertEqual "Fine. Be that way!" (Bob.hey ""))
, test "silence" (assertEqual "Fine. Be that way!" (Bob.hey "")) , test "prolonged silence" (assertEqual "Fine. Be that way!" (Bob.hey " "))
, test "prolonged silence" (assertEqual "Fine. Be that way!" (Bob.hey " ")) , test "alternate silences" (assertEqual "Fine. Be that way!" (Bob.hey "\t \n \t "))
, test "alternate silences" (assertEqual "Fine. Be that way!" (Bob.hey "\t \n \t ")) , test "on multiple line questions" (assertEqual "Whatever." (Bob.hey "\nDoes this cryogenic chamber make me look fat?\nno"))
, test "on multiple line questions" (assertEqual "Whatever." (Bob.hey "\nDoes this cryogenic chamber make me look fat?\nno")) ]
]
character : Int -> Int -> Random.Generator Char character : Int -> Int -> Random.Generator Char
character start end = character start end =
Random.map Char.fromCode (Random.int start end) Random.map Char.fromCode (Random.int start end)
anyCharacter : Random.Generator Char anyCharacter : Random.Generator Char
anyCharacter = anyCharacter =
character 32 126 character 32 126
uppercaseCharacter : Random.Generator Char uppercaseCharacter : Random.Generator Char
uppercaseCharacter = uppercaseCharacter =
character 65 90 character 65 90
listOfCharacters : Int -> Random.Generator Char -> Random.Generator (List Char) listOfCharacters : Int -> Random.Generator Char -> Random.Generator (List Char)
listOfCharacters length characterList = listOfCharacters length characterList =
Random.list length characterList Random.list length characterList
gibberish : Int -> Random.Generator Char -> String gibberish : Int -> Random.Generator Char -> String
gibberish length characterList = gibberish length characterList =
fst (Random.step (Random.map String.fromList (listOfCharacters length characterList)) (Random.initialSeed 424242)) fst (Random.step (Random.map String.fromList (listOfCharacters length characterList)) (Random.initialSeed 424242))
uppercaseGibberish : Int -> String uppercaseGibberish : Int -> String
uppercaseGibberish length = uppercaseGibberish length =
gibberish length uppercaseCharacter gibberish length uppercaseCharacter
gibberishQuestion : Int -> String gibberishQuestion : Int -> String
gibberishQuestion length = gibberishQuestion length =
(gibberish length anyCharacter) ++ "?" (gibberish length anyCharacter) ++ "?"
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -3,18 +3,18 @@ module DifferenceOfSquares exposing (..)
squareOfSum : Int -> Int squareOfSum : Int -> Int
squareOfSum n = squareOfSum n =
let let
sum = sum =
n * (n + 1) // 2 n * (n + 1) // 2
in in
sum * sum sum * sum
sumOfSquares : Int -> Int sumOfSquares : Int -> Int
sumOfSquares n = sumOfSquares n =
List.sum (List.map (\m -> m * m) [0..n]) List.sum (List.map (\m -> m * m) [0..n])
difference : Int -> Int difference : Int -> Int
difference n = difference n =
squareOfSum n - sumOfSquares n squareOfSum n - sumOfSquares n

View file

@ -6,30 +6,26 @@ import DifferenceOfSquares exposing (squareOfSum, sumOfSquares, difference)
tests : Test tests : Test
tests = tests =
suite suite "DifferenceOfSquares"
"DifferenceOfSquares" [ suite "square the sum of the numbers up to the given number"
[ suite [ test "square of sum 5" (assertEqual 225 (squareOfSum 5))
"square the sum of the numbers up to the given number" , test "square of sum 10" (assertEqual 3025 (squareOfSum 10))
[ test "square of sum 5" (assertEqual 225 (squareOfSum 5)) , test "square of sum 100" (assertEqual 25502500 (squareOfSum 100))
, test "square of sum 10" (assertEqual 3025 (squareOfSum 10)) ]
, test "square of sum 100" (assertEqual 25502500 (squareOfSum 100)) , suite "sum the squares of the numbers up to the given number"
[ test "sum of squares 5" (assertEqual 55 (sumOfSquares 5))
, test "sum of squares 10" (assertEqual 385 (sumOfSquares 10))
, test "sum of squares 100" (assertEqual 338350 (sumOfSquares 100))
]
, suite "subtract sum of squares from square of sums"
[ test "difference of squares 0" (assertEqual 0 (difference 0))
, test "difference of squares 5" (assertEqual 170 (difference 5))
, test "difference of squares 10" (assertEqual 2640 (difference 10))
, test "difference of squares 100" (assertEqual 25164150 (difference 100))
]
] ]
, suite
"sum the squares of the numbers up to the given number"
[ test "sum of squares 5" (assertEqual 55 (sumOfSquares 5))
, test "sum of squares 10" (assertEqual 385 (sumOfSquares 10))
, test "sum of squares 100" (assertEqual 338350 (sumOfSquares 100))
]
, suite
"subtract sum of squares from square of sums"
[ test "difference of squares 0" (assertEqual 0 (difference 0))
, test "difference of squares 5" (assertEqual 170 (difference 5))
, test "difference of squares 10" (assertEqual 2640 (difference 10))
, test "difference of squares 100" (assertEqual 25164150 (difference 100))
]
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -4,37 +4,37 @@ import Dict exposing (..)
type alias Grade = type alias Grade =
Int Int
type alias Student = type alias Student =
String String
type alias School = type alias School =
Dict Int (List Student) Dict Int (List Student)
empty : School empty : School
empty = empty =
Dict.empty Dict.empty
addStudent : Grade -> Student -> School -> School addStudent : Grade -> Student -> School -> School
addStudent grade student school = addStudent grade student school =
Dict.insert grade (List.sort (student :: (studentsInGrade grade school))) school Dict.insert grade (List.sort (student :: (studentsInGrade grade school))) school
studentsInGrade : Grade -> School -> List Student studentsInGrade : Grade -> School -> List Student
studentsInGrade grade school = studentsInGrade grade school =
case (Dict.get grade school) of case (Dict.get grade school) of
Just list -> Just list ->
list list
Nothing -> Nothing ->
[] []
allStudents : School -> List ( Grade, List Student ) allStudents : School -> List ( Grade, List Student )
allStudents school = allStudents school =
Dict.toList school |> List.sortBy fst Dict.toList school |> List.sortBy fst

View file

@ -6,70 +6,58 @@ import GradeSchool exposing (addStudent, studentsInGrade, allStudents)
tests : Test tests : Test
tests = tests =
suite suite "GradeSchool"
"GradeSchool" [ test "add student"
[ test (assertEqual [ "Aimee" ]
"add student" (GradeSchool.empty
(assertEqual |> addStudent 2 "Aimee"
[ "Aimee" ] |> studentsInGrade 2
(GradeSchool.empty )
|> addStudent 2 "Aimee" )
|> studentsInGrade 2 , test "add more students in same class"
) (assertEqual [ "Blair", "James", "Paul" ]
) (GradeSchool.empty
, test |> addStudent 2 "James"
"add more students in same class" |> addStudent 2 "Blair"
(assertEqual |> addStudent 2 "Paul"
[ "Blair", "James", "Paul" ] |> studentsInGrade 2
(GradeSchool.empty )
|> addStudent 2 "James" )
|> addStudent 2 "Blair" , test "add students to different grades"
|> addStudent 2 "Paul" (assertEqual [ [ "Chelsea" ], [ "Logan" ] ]
|> studentsInGrade 2 (let
) school =
) GradeSchool.empty
, test |> addStudent 3 "Chelsea"
"add students to different grades" |> addStudent 7 "Logan"
(assertEqual in
[ [ "Chelsea" ], [ "Logan" ] ] [ studentsInGrade 3 school, studentsInGrade 7 school ]
(let )
school = )
GradeSchool.empty , test "get students in a grade"
|> addStudent 3 "Chelsea" (assertEqual [ "Bradley", "Franklin" ]
|> addStudent 7 "Logan" (GradeSchool.empty
in |> addStudent 5 "Franklin"
[ studentsInGrade 3 school, studentsInGrade 7 school ] |> addStudent 5 "Bradley"
) |> addStudent 1 "Jeff"
) |> studentsInGrade 5
, test )
"get students in a grade" )
(assertEqual , test "get all students in the school"
[ "Bradley", "Franklin" ] (assertEqual [ ( 3, [ "Kyle" ] ), ( 4, [ "Christopher", "Jennifer" ] ), ( 6, [ "Kareem" ] ) ]
(GradeSchool.empty (GradeSchool.empty
|> addStudent 5 "Franklin" |> addStudent 4 "Jennifer"
|> addStudent 5 "Bradley" |> addStudent 6 "Kareem"
|> addStudent 1 "Jeff" |> addStudent 4 "Christopher"
|> studentsInGrade 5 |> addStudent 3 "Kyle"
) |> allStudents
) )
, test )
"get all students in the school" , test "get students in a non-existent grade"
(assertEqual (assertEqual [] (studentsInGrade 1 GradeSchool.empty))
[ ( 3, [ "Kyle" ] ), ( 4, [ "Christopher", "Jennifer" ] ), ( 6, [ "Kareem" ] ) ] ]
(GradeSchool.empty
|> addStudent 4 "Jennifer"
|> addStudent 6 "Kareem"
|> addStudent 4 "Christopher"
|> addStudent 3 "Kyle"
|> allStudents
)
)
, test
"get students in a non-existent grade"
(assertEqual [] (studentsInGrade 1 GradeSchool.empty))
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -5,10 +5,10 @@ import String exposing (length, toList)
distance : String -> String -> Maybe Int distance : String -> String -> Maybe Int
distance left right = distance left right =
if length left /= length right then if length left /= length right then
Nothing Nothing
else else
List.map2 (\l r -> l /= r) (toList left) (toList right) List.map2 (\l r -> l /= r) (toList left) (toList right)
|> List.filter identity |> List.filter identity
|> List.length |> List.length
|> Just |> Just

View file

@ -6,53 +6,38 @@ import Hamming exposing (distance)
tests : Test tests : Test
tests = tests =
suite suite "Hamming"
"Hamming" [ test "identical strands"
[ test (assertEqual (Just 0) (distance "A" "A"))
"identical strands" , test "long identical strands"
(assertEqual (Just 0) (distance "A" "A")) (assertEqual (Just 0) (distance "GGACTGA" "GGACTGA"))
, test , test "complete distance in single nucleotide strands"
"long identical strands" (assertEqual (Just 1) (distance "A" "G"))
(assertEqual (Just 0) (distance "GGACTGA" "GGACTGA")) , test "complete distance in small strands"
, test (assertEqual (Just 2) (distance "AG" "CT"))
"complete distance in single nucleotide strands" , test "small distance in small strands"
(assertEqual (Just 1) (distance "A" "G")) (assertEqual (Just 1) (distance "AT" "CT"))
, test , test "small distance"
"complete distance in small strands" (assertEqual (Just 1) (distance "GGACG" "GGTCG"))
(assertEqual (Just 2) (distance "AG" "CT")) , test "small distance in long strands"
, test (assertEqual (Just 2) (distance "ACCAGGG" "ACTATGG"))
"small distance in small strands" , test "non-unique character in first strand"
(assertEqual (Just 1) (distance "AT" "CT")) (assertEqual (Just 1) (distance "AGA" "AGG"))
, test , test "non-unique character in second strand"
"small distance" (assertEqual (Just 1) (distance "AGG" "AGA"))
(assertEqual (Just 1) (distance "GGACG" "GGTCG")) , test "large distance"
, test (assertEqual (Just 4) (distance "GATACA" "GCATAA"))
"small distance in long strands" , test "large distance in off-by-one strand"
(assertEqual (Just 2) (distance "ACCAGGG" "ACTATGG")) (assertEqual (Just 9) (distance "GGACGGATTCTG" "AGGACGGATTCT"))
, test , test "empty strands"
"non-unique character in first strand" (assertEqual (Just 0) (distance "" ""))
(assertEqual (Just 1) (distance "AGA" "AGG")) , test "disallow first strand longer"
, test (assertEqual Nothing (distance "AATG" "AAA"))
"non-unique character in second strand" , test "disallow second strand longer"
(assertEqual (Just 1) (distance "AGG" "AGA")) (assertEqual Nothing (distance "ATA" "AGTG"))
, test ]
"large distance"
(assertEqual (Just 4) (distance "GATACA" "GCATAA"))
, test
"large distance in off-by-one strand"
(assertEqual (Just 9) (distance "GGACGGATTCTG" "AGGACGGATTCT"))
, test
"empty strands"
(assertEqual (Just 0) (distance "" ""))
, test
"disallow first strand longer"
(assertEqual Nothing (distance "AATG" "AAA"))
, test
"disallow second strand longer"
(assertEqual Nothing (distance "ATA" "AGTG"))
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -3,9 +3,9 @@ module HelloWorld exposing (..)
helloWorld : Maybe String -> String helloWorld : Maybe String -> String
helloWorld name = helloWorld name =
case name of case name of
Just name -> Just name ->
"Hello, " ++ name ++ "!" "Hello, " ++ name ++ "!"
Nothing -> Nothing ->
"Hello, World!" "Hello, World!"

View file

@ -6,14 +6,13 @@ import HelloWorld exposing (helloWorld)
tests : Test tests : Test
tests = tests =
suite suite "Hello, World!"
"Hello, World!" [ test "Hello with no name" (assertEqual "Hello, World!" (helloWorld Nothing))
[ test "Hello with no name" (assertEqual "Hello, World!" (helloWorld Nothing)) , test "Hello to a sample name" (assertEqual "Hello, Alice!" (helloWorld (Just "Alice")))
, test "Hello to a sample name" (assertEqual "Hello, Alice!" (helloWorld (Just "Alice"))) , test "Hello to another sample name" (assertEqual "Hello, Bob!" (helloWorld (Just "Bob")))
, test "Hello to another sample name" (assertEqual "Hello, Bob!" (helloWorld (Just "Bob"))) ]
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -3,4 +3,4 @@ module Leap exposing (..)
isLeapYear : Int -> Bool isLeapYear : Int -> Bool
isLeapYear year = isLeapYear year =
year % 4 == 0 && (year % 100 /= 0 || year % 400 == 0) year % 4 == 0 && (year % 100 /= 0 || year % 400 == 0)

View file

@ -6,18 +6,17 @@ import Leap
tests : Test tests : Test
tests = tests =
suite suite "Leap"
"Leap" [ test "leap year" (assertEqual True (Leap.isLeapYear 1996))
[ test "leap year" (assertEqual True (Leap.isLeapYear 1996)) , test "non-leap year" (assertEqual False (Leap.isLeapYear 1997))
, test "non-leap year" (assertEqual False (Leap.isLeapYear 1997)) , test "non-leap even year" (assertEqual False (Leap.isLeapYear 1998))
, test "non-leap even year" (assertEqual False (Leap.isLeapYear 1998)) , test "century" (assertEqual False (Leap.isLeapYear 1900))
, test "century" (assertEqual False (Leap.isLeapYear 1900)) , test "second century" (assertEqual False (Leap.isLeapYear 1800))
, test "second century" (assertEqual False (Leap.isLeapYear 1800)) , test "fourth century" (assertEqual True (Leap.isLeapYear 2400))
, test "fourth century" (assertEqual True (Leap.isLeapYear 2400)) , test "y2k" (assertEqual True (Leap.isLeapYear 2000))
, test "y2k" (assertEqual True (Leap.isLeapYear 2000)) ]
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -3,57 +3,57 @@ module ListOps exposing (..)
length : List a -> Int length : List a -> Int
length list = length list =
foldl (\_ acc -> 1 + acc) 0 list foldl (\_ acc -> 1 + acc) 0 list
reverse : List a -> List a reverse : List a -> List a
reverse list = reverse list =
foldl (::) [] list foldl (::) [] list
foldl : (a -> b -> b) -> b -> List a -> b foldl : (a -> b -> b) -> b -> List a -> b
foldl f acc list = foldl f acc list =
case list of case list of
[] -> [] ->
acc acc
head :: tail -> head :: tail ->
foldl f (f head acc) tail foldl f (f head acc) tail
foldr : (a -> b -> b) -> b -> List a -> b foldr : (a -> b -> b) -> b -> List a -> b
foldr f acc list = foldr f acc list =
case list of case list of
[] -> [] ->
acc acc
head :: tail -> head :: tail ->
f head (foldr f acc tail) f head (foldr f acc tail)
map : (a -> b) -> List a -> List b map : (a -> b) -> List a -> List b
map f list = map f list =
foldr (\x acc -> f x :: acc) [] list foldr (\x acc -> f x :: acc) [] list
filter : (a -> Bool) -> List a -> List a filter : (a -> Bool) -> List a -> List a
filter f list = filter f list =
foldr foldr
(\x acc -> (\x acc ->
if f x then if f x then
x :: acc x :: acc
else else
acc acc
) )
[] []
list list
append : List a -> List a -> List a append : List a -> List a -> List a
append xs ys = append xs ys =
foldr (::) ys xs foldr (::) ys xs
concat : List (List a) -> List a concat : List (List a) -> List a
concat list = concat list =
foldr append [] list foldr append [] list

View file

@ -6,61 +6,48 @@ import ListOps exposing (..)
tests : Test tests : Test
tests = tests =
suite suite "List Ops"
"List Ops" [ suite "length"
[ suite [ test "empty list" (assertEqual 0 (length []))
"length" , test "non-empty list" (assertEqual 4 (length [1..4]))
[ test "empty list" (assertEqual 0 (length [])) ]
, test "non-empty list" (assertEqual 4 (length [1..4])) , suite "reverse"
[ test "empty list" (assertEqual [] (reverse []))
, test "non-empty list" (assertEqual [ 4, 3, 2, 1 ] (reverse [1..4]))
]
, suite "map"
[ test "empty list" (assertEqual [] (map ((+) 1) []))
, test "non-empty list" (assertEqual [2..5] (map ((+) 1) [1..4]))
]
, suite "filter"
[ test "empty list" (assertEqual [] (filter (\_ -> True) []))
, test "non-empty list"
(assertEqual [ 2, 4 ] (filter (\x -> x % 2 == 0) [1..4]))
]
, suite "foldl"
[ test "empty list" (assertEqual 0 (foldl (+) 0 []))
, test "non-empty list" (assertEqual 10 (foldl (+) 0 [1..4]))
]
, suite "foldr"
[ test "empty list" (assertEqual 0 (foldr (+) 0 []))
, test "non-empty list" (assertEqual 10 (foldr (+) 0 [1..4]))
]
, suite "append"
[ test "empty lists" (assertEqual [] (append [] []))
, test "empty and non-empty lists"
(assertEqual [1..4] (append [] [1..4]))
, test "non-empty and empty lists"
(assertEqual [1..4] (append [1..4] []))
, test "non-empty lists" (assertEqual [1..8] (append [1..4] [5..8]))
]
, suite "concat"
[ test "empty list" (assertEqual [] (concat []))
, test "list of lists"
(assertEqual [1..10] (concat [ [1..3], [], [4..7], [8..10] ]))
]
] ]
, suite
"reverse"
[ test "empty list" (assertEqual [] (reverse []))
, test "non-empty list" (assertEqual [ 4, 3, 2, 1 ] (reverse [1..4]))
]
, suite
"map"
[ test "empty list" (assertEqual [] (map ((+) 1) []))
, test "non-empty list" (assertEqual [2..5] (map ((+) 1) [1..4]))
]
, suite
"filter"
[ test "empty list" (assertEqual [] (filter (\_ -> True) []))
, test
"non-empty list"
(assertEqual [ 2, 4 ] (filter (\x -> x % 2 == 0) [1..4]))
]
, suite
"foldl"
[ test "empty list" (assertEqual 0 (foldl (+) 0 []))
, test "non-empty list" (assertEqual 10 (foldl (+) 0 [1..4]))
]
, suite
"foldr"
[ test "empty list" (assertEqual 0 (foldr (+) 0 []))
, test "non-empty list" (assertEqual 10 (foldr (+) 0 [1..4]))
]
, suite
"append"
[ test "empty lists" (assertEqual [] (append [] []))
, test
"empty and non-empty lists"
(assertEqual [1..4] (append [] [1..4]))
, test
"non-empty and empty lists"
(assertEqual [1..4] (append [1..4] []))
, test "non-empty lists" (assertEqual [1..8] (append [1..4] [5..8]))
]
, suite
"concat"
[ test "empty list" (assertEqual [] (concat []))
, test
"list of lists"
(assertEqual [1..10] (concat [ [1..3], [], [4..7], [8..10] ]))
]
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -5,45 +5,45 @@ import String
version : Int version : Int
version = version =
2 2
type alias NucleotideCounts = type alias NucleotideCounts =
{ a : Int { a : Int
, t : Int , t : Int
, c : Int , c : Int
, g : Int , g : Int
} }
init : NucleotideCounts init : NucleotideCounts
init = init =
{ a = 0 { a = 0
, t = 0 , t = 0
, c = 0 , c = 0
, g = 0 , g = 0
} }
update : Char -> NucleotideCounts -> NucleotideCounts update : Char -> NucleotideCounts -> NucleotideCounts
update char counts = update char counts =
case char of case char of
'A' -> 'A' ->
{ counts | a = counts.a + 1 } { counts | a = counts.a + 1 }
'T' -> 'T' ->
{ counts | t = counts.t + 1 } { counts | t = counts.t + 1 }
'C' -> 'C' ->
{ counts | c = counts.c + 1 } { counts | c = counts.c + 1 }
'G' -> 'G' ->
{ counts | g = counts.g + 1 } { counts | g = counts.g + 1 }
_ -> _ ->
counts counts
nucleotideCounts : String -> NucleotideCounts nucleotideCounts : String -> NucleotideCounts
nucleotideCounts sequence = nucleotideCounts sequence =
String.foldl update init sequence String.foldl update init sequence

View file

@ -6,32 +6,24 @@ import NucleotideCount exposing (nucleotideCounts, version)
tests : Test tests : Test
tests = tests =
suite suite "NucleotideCount"
"NucleotideCount" [ test "the solution is for the correct version of the test"
[ test (assertEqual 2 version)
"the solution is for the correct version of the test" , test "empty dna strand has no nucleotides"
(assertEqual 2 version) (assertEqual { a = 0, t = 0, c = 0, g = 0 }
, test (nucleotideCounts "")
"empty dna strand has no nucleotides" )
(assertEqual , test "repetitive-sequence-has-only-guanosine"
{ a = 0, t = 0, c = 0, g = 0 } (assertEqual { a = 0, t = 0, c = 0, g = 8 }
(nucleotideCounts "") (nucleotideCounts "GGGGGGGG")
) )
, test , test "counts all nucleotides"
"repetitive-sequence-has-only-guanosine" (assertEqual { a = 20, t = 21, c = 12, g = 17 }
(assertEqual (nucleotideCounts "AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC")
{ a = 0, t = 0, c = 0, g = 8 } )
(nucleotideCounts "GGGGGGGG") ]
)
, test
"counts all nucleotides"
(assertEqual
{ a = 20, t = 21, c = 12, g = 17 }
(nucleotideCounts "AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC")
)
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -5,13 +5,13 @@ import String exposing (toLower, contains, fromChar)
isPangram : String -> Bool isPangram : String -> Bool
isPangram sentence = isPangram sentence =
let let
normalized = normalized =
toLower sentence toLower sentence
in in
String.all (\c -> contains (fromChar c) normalized) alphabet String.all (\c -> contains (fromChar c) normalized) alphabet
alphabet : String alphabet : String
alphabet = alphabet =
"abcdefghijklmnopqrstuvwxyz" "abcdefghijklmnopqrstuvwxyz"

View file

@ -6,65 +6,46 @@ import Pangram exposing (isPangram)
tests : Test tests : Test
tests = tests =
suite suite "Pangram"
"Pangram" [ test "sentence empty"
[ test (assertEqual False
"sentence empty" (isPangram "")
(assertEqual )
False , test "pangram with only lower case"
(isPangram "") (assertEqual True
) (isPangram "the quick brown fox jumps over the lazy dog")
, test )
"pangram with only lower case" , test "missing character 'x'"
(assertEqual (assertEqual False
True (isPangram "a quick movement of the enemy will jeopardize five gunboats")
(isPangram "the quick brown fox jumps over the lazy dog") )
) , test "another missing character 'x'"
, test (assertEqual False
"missing character 'x'" (isPangram "the quick brown fish jumps over the lazy dog")
(assertEqual )
False , test "pangram with underscores"
(isPangram "a quick movement of the enemy will jeopardize five gunboats") (assertEqual True
) (isPangram "the_quick_brown_fox_jumps_over_the_lazy_dog")
, test )
"another missing character 'x'" , test "pangram with numbers"
(assertEqual (assertEqual True
False (isPangram "the 1 quick brown fox jumps over the 2 lazy dogs")
(isPangram "the quick brown fish jumps over the lazy dog") )
) , test "missing letters replaced by numbers"
, test (assertEqual False
"pangram with underscores" (isPangram "7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog")
(assertEqual )
True , test "pangram with mixed case and punctuation"
(isPangram "the_quick_brown_fox_jumps_over_the_lazy_dog") (assertEqual True
) (isPangram "\"Five quacking Zephyrs jolt my wax bed.\"")
, test )
"pangram with numbers" , test "pangram with non ascii characters"
(assertEqual (assertEqual True
True (isPangram "Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich.")
(isPangram "the 1 quick brown fox jumps over the 2 lazy dogs") )
) ]
, test
"missing letters replaced by numbers"
(assertEqual
False
(isPangram "7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog")
)
, test
"pangram with mixed case and punctuation"
(assertEqual
True
(isPangram "\"Five quacking Zephyrs jolt my wax bed.\"")
)
, test
"pangram with non ascii characters"
(assertEqual
True
(isPangram "Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich.")
)
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -4,41 +4,41 @@ import String
nums = nums =
[ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' ] [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' ]
getNumber : String -> Maybe String getNumber : String -> Maybe String
getNumber text = getNumber text =
getValidNum (String.filter isDigit text) getValidNum (String.filter isDigit text)
isDigit : Char -> Bool isDigit : Char -> Bool
isDigit char = isDigit char =
List.any (\n -> n == char) nums List.any (\n -> n == char) nums
getValidNum : String -> Maybe String getValidNum : String -> Maybe String
getValidNum num = getValidNum num =
if String.length num == 10 then if String.length num == 10 then
Just num Just num
else if (String.length num == 11) && (String.left 1 num == "1") then else if (String.length num == 11) && (String.left 1 num == "1") then
Just (String.dropLeft 1 num) Just (String.dropLeft 1 num)
else else
Nothing Nothing
prettyPrint : String -> Maybe String prettyPrint : String -> Maybe String
prettyPrint input = prettyPrint input =
Maybe.map formatNumber (getNumber input) Maybe.map formatNumber (getNumber input)
formatNumber : String -> String formatNumber : String -> String
formatNumber input = formatNumber input =
String.concat String.concat
[ "(" [ "("
, (String.slice 0 3 input) , (String.slice 0 3 input)
, ") " , ") "
, (String.slice 3 6 input) , (String.slice 3 6 input)
, "-" , "-"
, (String.slice 6 10 input) , (String.slice 6 10 input)
] ]

View file

@ -6,47 +6,34 @@ import PhoneNumber exposing (getNumber, prettyPrint)
tests : Test tests : Test
tests = tests =
suite suite "PhoneNumber"
"PhoneNumber" [ test "cleans number"
[ test (assertEqual (Just "1234567890") (getNumber "(123) 456-7890"))
"cleans number" , test "cleans number with dots"
(assertEqual (Just "1234567890") (getNumber "(123) 456-7890")) (assertEqual (Just "1234567890") (getNumber "123.456.7890"))
, test , test "valid when 11 digits and first is 1"
"cleans number with dots" (assertEqual (Just "1234567890") (getNumber "11234567890"))
(assertEqual (Just "1234567890") (getNumber "123.456.7890")) , test "invalid when 11 digits"
, test (assertEqual Nothing (getNumber "21234567890"))
"valid when 11 digits and first is 1" , test "invalid when 9 digits"
(assertEqual (Just "1234567890") (getNumber "11234567890")) (assertEqual Nothing (getNumber "123456789"))
, test , test "invalid when 12 digits"
"invalid when 11 digits" (assertEqual Nothing (getNumber "123456789012"))
(assertEqual Nothing (getNumber "21234567890")) , test "invalid when empty"
, test (assertEqual Nothing (getNumber ""))
"invalid when 9 digits" , test "invalid when no digits present"
(assertEqual Nothing (getNumber "123456789")) (assertEqual Nothing (getNumber " (-) "))
, test , test "valid with leading characters"
"invalid when 12 digits" (assertEqual (Just "1234567890") (getNumber "my number is 123 456 7890"))
(assertEqual Nothing (getNumber "123456789012")) , test "valid with trailing characters"
, test (assertEqual (Just "1234567890") (getNumber "123 456 7890 - bob"))
"invalid when empty" , test "pretty print"
(assertEqual Nothing (getNumber "")) (assertEqual (Just "(123) 456-7890") (prettyPrint "1234567890"))
, test , test "pretty print with full us phone number"
"invalid when no digits present" (assertEqual (Just "(123) 456-7890") (prettyPrint "11234567890"))
(assertEqual Nothing (getNumber " (-) ")) ]
, test
"valid with leading characters"
(assertEqual (Just "1234567890") (getNumber "my number is 123 456 7890"))
, test
"valid with trailing characters"
(assertEqual (Just "1234567890") (getNumber "123 456 7890 - bob"))
, test
"pretty print"
(assertEqual (Just "(123) 456-7890") (prettyPrint "1234567890"))
, test
"pretty print with full us phone number"
(assertEqual (Just "(123) 456-7890") (prettyPrint "11234567890"))
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -5,26 +5,26 @@ import String
raindrops : Int -> String raindrops : Int -> String
raindrops number = raindrops number =
let let
drops = drops =
[ if number % 3 == 0 then [ if number % 3 == 0 then
"Pling" "Pling"
else else
"" ""
, if number % 5 == 0 then , if number % 5 == 0 then
"Plang" "Plang"
else else
"" ""
, if number % 7 == 0 then , if number % 7 == 0 then
"Plong" "Plong"
else else
"" ""
] ]
result = result =
String.join "" drops String.join "" drops
in in
if result == "" then if result == "" then
toString number toString number
else else
result result

View file

@ -6,26 +6,25 @@ import Raindrops exposing (raindrops)
tests : Test tests : Test
tests = tests =
suite suite "Raindrops"
"Raindrops" [ test "1" (assertEqual "1" (raindrops 1))
[ test "1" (assertEqual "1" (raindrops 1)) , test "3" (assertEqual "Pling" (raindrops 3))
, test "3" (assertEqual "Pling" (raindrops 3)) , test "5" (assertEqual "Plang" (raindrops 5))
, test "5" (assertEqual "Plang" (raindrops 5)) , test "7" (assertEqual "Plong" (raindrops 7))
, test "7" (assertEqual "Plong" (raindrops 7)) , test "6" (assertEqual "Pling" (raindrops 6))
, test "6" (assertEqual "Pling" (raindrops 6)) , test "9" (assertEqual "Pling" (raindrops 9))
, test "9" (assertEqual "Pling" (raindrops 9)) , test "10" (assertEqual "Plang" (raindrops 10))
, test "10" (assertEqual "Plang" (raindrops 10)) , test "14" (assertEqual "Plong" (raindrops 14))
, test "14" (assertEqual "Plong" (raindrops 14)) , test "15" (assertEqual "PlingPlang" (raindrops 15))
, test "15" (assertEqual "PlingPlang" (raindrops 15)) , test "21" (assertEqual "PlingPlong" (raindrops 21))
, test "21" (assertEqual "PlingPlong" (raindrops 21)) , test "25" (assertEqual "Plang" (raindrops 25))
, test "25" (assertEqual "Plang" (raindrops 25)) , test "35" (assertEqual "PlangPlong" (raindrops 35))
, test "35" (assertEqual "PlangPlong" (raindrops 35)) , test "49" (assertEqual "Plong" (raindrops 49))
, test "49" (assertEqual "Plong" (raindrops 49)) , test "52" (assertEqual "52" (raindrops 52))
, test "52" (assertEqual "52" (raindrops 52)) , test "105" (assertEqual "PlingPlangPlong" (raindrops 105))
, test "105" (assertEqual "PlingPlangPlong" (raindrops 105)) ]
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -5,12 +5,12 @@ import String
toRNA : String -> Result Char String toRNA : String -> Result Char String
toRNA dna = toRNA dna =
dna dna
|> String.toList |> String.toList
|> List.map toRNANucleotide |> List.map toRNANucleotide
|> resultExtraCombine |> resultExtraCombine
|> Result.map (List.map String.fromChar) |> Result.map (List.map String.fromChar)
|> Result.map (String.join "") |> Result.map (String.join "")
@ -19,23 +19,23 @@ toRNA dna =
resultExtraCombine : List (Result x a) -> Result x (List a) resultExtraCombine : List (Result x a) -> Result x (List a)
resultExtraCombine = resultExtraCombine =
List.foldr (Result.map2 (::)) (Ok []) List.foldr (Result.map2 (::)) (Ok [])
toRNANucleotide : Char -> Result Char Char toRNANucleotide : Char -> Result Char Char
toRNANucleotide nuc = toRNANucleotide nuc =
case nuc of case nuc of
'C' -> 'C' ->
Ok 'G' Ok 'G'
'G' -> 'G' ->
Ok 'C' Ok 'C'
'A' -> 'A' ->
Ok 'U' Ok 'U'
'T' -> 'T' ->
Ok 'A' Ok 'A'
_ -> _ ->
Err nuc Err nuc

View file

@ -6,32 +6,24 @@ import RNATranscription exposing (toRNA)
tests : Test tests : Test
tests = tests =
suite suite "RNATranscription"
"RNATranscription" [ test "complement of cytosine is guanine"
[ test (assertEqual (Ok "G") (toRNA "C"))
"complement of cytosine is guanine" , test "complement of guanine is cytosine"
(assertEqual (Ok "G") (toRNA "C")) (assertEqual (Ok "C") (toRNA "G"))
, test , test "complement of thymine is adenine"
"complement of guanine is cytosine" (assertEqual (Ok "A") (toRNA "T"))
(assertEqual (Ok "C") (toRNA "G")) , test "complement of adenine is uracil"
, test (assertEqual (Ok "U") (toRNA "A"))
"complement of thymine is adenine" , test "complement"
(assertEqual (Ok "A") (toRNA "T")) (assertEqual (Ok "UGCACCAGAAUU") (toRNA "ACGTGGTCTTAA"))
, test , test "correctly handles completely invalid input"
"complement of adenine is uracil" (assertEqual (Err 'X') (toRNA "XXX"))
(assertEqual (Ok "U") (toRNA "A")) , test "correctly handles partially invalid input"
, test (assertEqual (Err 'U') (toRNA "UGAAXXXGACAUG"))
"complement" ]
(assertEqual (Ok "UGCACCAGAAUU") (toRNA "ACGTGGTCTTAA"))
, test
"correctly handles completely invalid input"
(assertEqual (Err 'X') (toRNA "XXX"))
, test
"correctly handles partially invalid input"
(assertEqual (Err 'U') (toRNA "UGAAXXXGACAUG"))
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -4,95 +4,95 @@ import String
type Bearing type Bearing
= North = North
| East | East
| South | South
| West | West
type alias Robot = type alias Robot =
{ bearing : Bearing { bearing : Bearing
, coordinates : { x : Int, y : Int } , coordinates : { x : Int, y : Int }
} }
defaultRobot : Robot defaultRobot : Robot
defaultRobot = defaultRobot =
{ bearing = North { bearing = North
, coordinates = { x = 0, y = 0 } , coordinates = { x = 0, y = 0 }
} }
turnRight : Robot -> Robot turnRight : Robot -> Robot
turnRight robot = turnRight robot =
case robot.bearing of case robot.bearing of
North -> North ->
{ robot | bearing = East } { robot | bearing = East }
East -> East ->
{ robot | bearing = South } { robot | bearing = South }
South -> South ->
{ robot | bearing = West } { robot | bearing = West }
West -> West ->
{ robot | bearing = North } { robot | bearing = North }
turnLeft : Robot -> Robot turnLeft : Robot -> Robot
turnLeft robot = turnLeft robot =
case robot.bearing of case robot.bearing of
North -> North ->
{ robot | bearing = West } { robot | bearing = West }
West -> West ->
{ robot | bearing = South } { robot | bearing = South }
South -> South ->
{ robot | bearing = East } { robot | bearing = East }
East -> East ->
{ robot | bearing = North } { robot | bearing = North }
advance : Robot -> Robot advance : Robot -> Robot
advance { bearing, coordinates } = advance { bearing, coordinates } =
let let
updated = updated =
case bearing of case bearing of
North -> North ->
{ coordinates | y = coordinates.y + 1 } { coordinates | y = coordinates.y + 1 }
East -> East ->
{ coordinates | x = coordinates.x + 1 } { coordinates | x = coordinates.x + 1 }
South -> South ->
{ coordinates | y = coordinates.y - 1 } { coordinates | y = coordinates.y - 1 }
West -> West ->
{ coordinates | x = coordinates.x - 1 } { coordinates | x = coordinates.x - 1 }
in in
{ bearing = bearing, coordinates = updated } { bearing = bearing, coordinates = updated }
simulate : String -> Robot -> Robot simulate : String -> Robot -> Robot
simulate directions robot = simulate directions robot =
let let
action direction = action direction =
case direction of case direction of
'L' -> 'L' ->
turnLeft turnLeft
'R' -> 'R' ->
turnRight turnRight
'A' -> 'A' ->
advance advance
_ -> _ ->
identity identity
in in
directions directions
|> String.toList |> String.toList
|> List.map action |> List.map action
|> List.foldl (\a r -> a r) robot |> List.foldl (\a r -> a r) robot

View file

@ -6,124 +6,112 @@ import RobotSimulator exposing (defaultRobot, Robot, Bearing(North, East, West,
tests : Test tests : Test
tests = tests =
suite suite "RobotSimulator"
"RobotSimulator" [ suite "init"
[ suite (let
"init" robot =
(let defaultRobot
robot = in
defaultRobot [ test "coordinates" (assertEqual { x = 0, y = 0 } robot.coordinates)
in , test "bearing" (assertEqual North robot.bearing)
[ test "coordinates" (assertEqual { x = 0, y = 0 } robot.coordinates) ]
, test "bearing" (assertEqual North robot.bearing) )
] , suite "setup"
) (let
, suite robot =
"setup" Robot South { x = -1, y = 1 }
(let in
robot = [ test "coordinates" (assertEqual { x = -1, y = 1 } robot.coordinates)
Robot South { x = -1, y = 1 } , test "bearing" (assertEqual South robot.bearing)
in ]
[ test "coordinates" (assertEqual { x = -1, y = 1 } robot.coordinates) )
, test "bearing" (assertEqual South robot.bearing) , suite "turn right"
] ([1..3]
) |> List.scanl (\_ r -> turnRight r) defaultRobot
, suite |> List.map .bearing
"turn right" |> assertionList [ North, East, South, West ]
([1..3] |> List.map defaultTest
|> List.scanl (\_ r -> turnRight r) defaultRobot )
|> List.map .bearing , suite "turn left"
|> assertionList [ North, East, South, West ] ([1..3]
|> List.map defaultTest |> List.scanl (\_ r -> turnLeft r) defaultRobot
) |> List.map .bearing
, suite |> assertionList [ North, West, South, East ]
"turn left" |> List.map defaultTest
([1..3] )
|> List.scanl (\_ r -> turnLeft r) defaultRobot , suite "advance positive north"
|> List.map .bearing (let
|> assertionList [ North, West, South, East ] robot =
|> List.map defaultTest Robot North { x = 0, y = 0 }
) |> advance
, suite in
"advance positive north" [ test "coordinates" (assertEqual { x = 0, y = 1 } robot.coordinates)
(let , test "bearing" (assertEqual North robot.bearing)
robot = ]
Robot North { x = 0, y = 0 } )
|> advance , suite "advance positive east"
in (let
[ test "coordinates" (assertEqual { x = 0, y = 1 } robot.coordinates) robot =
, test "bearing" (assertEqual North robot.bearing) Robot East { x = 0, y = 0 }
] |> advance
) in
, suite [ test "coordinates" (assertEqual { x = 1, y = 0 } robot.coordinates)
"advance positive east" , test "bearing" (assertEqual East robot.bearing)
(let ]
robot = )
Robot East { x = 0, y = 0 } , suite "advance negative south"
|> advance (let
in robot =
[ test "coordinates" (assertEqual { x = 1, y = 0 } robot.coordinates) Robot South { x = 0, y = 0 }
, test "bearing" (assertEqual East robot.bearing) |> advance
] in
) [ test "coordinates" (assertEqual { x = 0, y = -1 } robot.coordinates)
, suite , test "bearing" (assertEqual South robot.bearing)
"advance negative south" ]
(let )
robot = , suite "advance positive west"
Robot South { x = 0, y = 0 } (let
|> advance robot =
in Robot West { x = 0, y = 0 }
[ test "coordinates" (assertEqual { x = 0, y = -1 } robot.coordinates) |> advance
, test "bearing" (assertEqual South robot.bearing) in
] [ test "coordinates" (assertEqual { x = -1, y = 0 } robot.coordinates)
) , test "bearing" (assertEqual West robot.bearing)
, suite ]
"advance positive west" )
(let , suite "simulate prog 1"
robot = (let
Robot West { x = 0, y = 0 } robot =
|> advance Robot North { x = 0, y = 0 }
in |> simulate "LAAARALA"
[ test "coordinates" (assertEqual { x = -1, y = 0 } robot.coordinates) in
, test "bearing" (assertEqual West robot.bearing) [ test "coordinates" (assertEqual { x = -4, y = 1 } robot.coordinates)
] , test "bearing" (assertEqual West robot.bearing)
) ]
, suite )
"simulate prog 1" , suite "simulate prog 2"
(let (let
robot = robot =
Robot North { x = 0, y = 0 } Robot East { x = 2, y = -7 }
|> simulate "LAAARALA" |> simulate "RRAAAAALA"
in in
[ test "coordinates" (assertEqual { x = -4, y = 1 } robot.coordinates) [ test "coordinates" (assertEqual { x = -3, y = -8 } robot.coordinates)
, test "bearing" (assertEqual West robot.bearing) , test "bearing" (assertEqual South robot.bearing)
] ]
) )
, suite , suite "simulate prog 3"
"simulate prog 2" (let
(let robot =
robot = Robot South { x = 8, y = 4 }
Robot East { x = 2, y = -7 } |> simulate "LAAARRRALLLL"
|> simulate "RRAAAAALA" in
in [ test "coordinates" (assertEqual { x = 11, y = 5 } robot.coordinates)
[ test "coordinates" (assertEqual { x = -3, y = -8 } robot.coordinates) , test "bearing" (assertEqual North robot.bearing)
, test "bearing" (assertEqual South robot.bearing) ]
] )
) ]
, suite
"simulate prog 3"
(let
robot =
Robot South { x = 8, y = 4 }
|> simulate "LAAARRRALLLL"
in
[ test "coordinates" (assertEqual { x = 11, y = 5 } robot.coordinates)
, test "bearing" (assertEqual North robot.bearing)
]
)
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -7,63 +7,63 @@ import Regex
{- {-
To the unaware: this was written by a very green elmer, so don't consider To the unaware: this was written by a very green elmer, so don't consider
it an idiomatic exemplar to emulate. it an idiomatic exemplar to emulate.
-} -}
version = version =
2 2
encode : String -> String encode : String -> String
encode string = encode string =
String.toList string String.toList string
|> List.foldr countChars [] |> List.foldr countChars []
|> List.map stringifyCounts |> List.map stringifyCounts
|> String.join "" |> String.join ""
countChars : a -> List ( number, a ) -> List ( number, a ) countChars : a -> List ( number, a ) -> List ( number, a )
countChars current counted = countChars current counted =
case head counted of case head counted of
Just ( count, previous ) -> Just ( count, previous ) ->
if previous == current then if previous == current then
( count + 1, current ) :: withDefault [] (tail counted) ( count + 1, current ) :: withDefault [] (tail counted)
else else
( 1, current ) :: counted ( 1, current ) :: counted
Nothing -> Nothing ->
[ ( 1, current ) ] [ ( 1, current ) ]
stringifyCounts : ( number, Char ) -> String stringifyCounts : ( number, Char ) -> String
stringifyCounts ( count, char ) = stringifyCounts ( count, char ) =
if count > 1 then if count > 1 then
toString count ++ fromChar char toString count ++ fromChar char
else else
fromChar char fromChar char
decode : String -> String decode : String -> String
decode string = decode string =
string string
|> Regex.find Regex.All (Regex.regex "(\\d+)|(\\D)") |> Regex.find Regex.All (Regex.regex "(\\d+)|(\\D)")
|> List.map .match |> List.map .match
|> List.foldl expandCounts ( "", Nothing ) |> List.foldl expandCounts ( "", Nothing )
|> fst |> fst
expandCounts : String -> ( String, Maybe Int ) -> ( String, Maybe Int ) expandCounts : String -> ( String, Maybe Int ) -> ( String, Maybe Int )
expandCounts match ( result, count ) = expandCounts match ( result, count ) =
case count of case count of
Just number -> Just number ->
( result ++ String.repeat number match, Nothing ) ( result ++ String.repeat number match, Nothing )
Nothing -> Nothing ->
case String.toInt match of case String.toInt match of
Ok number -> Ok number ->
( result, Just number ) ( result, Just number )
Err _ -> Err _ ->
( result ++ match, Nothing ) ( result ++ match, Nothing )

View file

@ -10,57 +10,54 @@ import Char
{- {-
Currently disabled until elm-check is updated to support Elm 0.17 Currently disabled until elm-check is updated to support Elm 0.17
Welcome! This is a property based test which will generate a bunch of random Welcome! This is a property based test which will generate a bunch of random
test cases in an attempt to find edge cases in your solution. If all goes well, test cases in an attempt to find edge cases in your solution. If all goes well,
any code that passes the regular tests should be fine here as well. If it goes any code that passes the regular tests should be fine here as well. If it goes
less well, this should hopefully narrow the failure down to a useful test case. less well, this should hopefully narrow the failure down to a useful test case.
Good luck! Good luck!
-} -}
claims : Check.Claim claims : Check.Claim
claims = claims =
suite suite "List Reverse"
"List Reverse" [ claim "Encoding and decoding yields the original string"
[ claim `that` (\input -> decode (encode (S.concat input)))
"Encoding and decoding yields the original string" `is` S.concat
`that` (\input -> decode (encode (S.concat input))) `for` inputProducer
`is` S.concat ]
`for` inputProducer
]
inputProducer : P.Producer (List String) inputProducer : P.Producer (List String)
inputProducer = inputProducer =
P.tuple ( P.rangeInt 0 1001, upperCaseLetter ) P.tuple ( P.rangeInt 0 1001, upperCaseLetter )
|> P.convert |> P.convert (\( n, c ) -> S.repeat n (S.fromChar c))
(\( n, c ) -> S.repeat n (S.fromChar c)) (\s ->
(\s -> ( S.length s
( S.length s , S.toList s |> List.head |> crashIfNothing
, S.toList s |> List.head |> crashIfNothing )
) )
) |> P.list
|> P.list
upperCaseLetter : P.Producer Char upperCaseLetter : P.Producer Char
upperCaseLetter = upperCaseLetter =
P.filter Char.isUpper P.upperCaseChar P.filter Char.isUpper P.upperCaseChar
crashIfNothing : Maybe a -> a crashIfNothing : Maybe a -> a
crashIfNothing a = crashIfNothing a =
case a of case a of
Just a -> Just a ->
a a
Nothing -> Nothing ->
Debug.crash "Nothing!" Debug.crash "Nothing!"
propertyTests : ElmTest.Test propertyTests : ElmTest.Test
propertyTests = propertyTests =
Check.Test.evidenceToTest (quickCheck claims) Check.Test.evidenceToTest (quickCheck claims)

View file

@ -6,50 +6,36 @@ import RunLengthEncoding exposing (version, decode, encode)
tests : Test tests : Test
tests = tests =
suite suite "RunLengthEncoding"
"RunLengthEncoding" [ test "the solution is for the correct version of the test"
[ test (assertEqual 2 version)
"the solution is for the correct version of the test" , test "encode simple"
(assertEqual 2 version) (assertEqual "2A3B4C" (encode "AABBBCCCC"))
, test , test "decode simple"
"encode simple" (assertEqual "AABBBCCCC" (decode "2A3B4C"))
(assertEqual "2A3B4C" (encode "AABBBCCCC")) , test "encode with single values"
, test (assertEqual "12WB12W3B24WB"
"decode simple" (encode "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB")
(assertEqual "AABBBCCCC" (decode "2A3B4C")) )
, test , test "decode with single values"
"encode with single values" (assertEqual "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB"
(assertEqual (decode "12WB12W3B24WB")
"12WB12W3B24WB" )
(encode "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB") , test "(decode (encode (...)) combination"
) (assertEqual "zzz ZZ zZ"
, test (decode (encode "zzz ZZ zZ"))
"decode with single values" )
(assertEqual , test "decode with a x10 value"
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" (assertEqual "WWWWWWWWWW"
(decode "12WB12W3B24WB") (decode "10W")
) )
, test , test "encode unicode"
"(decode (encode (...)) combination" (assertEqual "32" (encode ""))
(assertEqual , test "decode unicode"
"zzz ZZ zZ" (assertEqual "" (decode "32"))
(decode (encode "zzz ZZ zZ")) ]
)
, test
"decode with a x10 value"
(assertEqual
"WWWWWWWWWW"
(decode "10W")
)
, test
"encode unicode"
(assertEqual "32" (encode ""))
, test
"decode unicode"
(assertEqual "" (decode "32"))
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -7,27 +7,27 @@ import Result
slices : Int -> String -> Result String (List (List Int)) slices : Int -> String -> Result String (List (List Int))
slices size input = slices size input =
if size < 1 then if size < 1 then
Err ("Invalid size: " ++ toString size) Err ("Invalid size: " ++ toString size)
else else
String.split "" input String.split "" input
|> List.map String.toInt |> List.map String.toInt
|> combine |> combine
|> Result.map (takeRuns size) |> Result.map (takeRuns size)
takeRuns : Int -> List Int -> List (List Int) takeRuns : Int -> List Int -> List (List Int)
takeRuns size numbers = takeRuns size numbers =
let let
candidate = candidate =
List.take size numbers List.take size numbers
in in
if List.length candidate < size || size < 1 then if List.length candidate < size || size < 1 then
[] []
else else
candidate :: takeRuns size (List.drop 1 numbers) candidate :: takeRuns size (List.drop 1 numbers)
combine : List (Result x a) -> Result x (List a) combine : List (Result x a) -> Result x (List a)
combine = combine =
List.foldr (Result.map2 (::)) (Ok []) List.foldr (Result.map2 (::)) (Ok [])

View file

@ -6,59 +6,42 @@ import Series exposing (slices)
tests : Test tests : Test
tests = tests =
suite suite "Series"
"Series" [ test "slices of one"
[ test (assertEqual (Ok [ [ 0 ], [ 1 ], [ 2 ], [ 3 ], [ 4 ] ])
"slices of one" (slices 1 "01234")
(assertEqual )
(Ok [ [ 0 ], [ 1 ], [ 2 ], [ 3 ], [ 4 ] ]) , test "slices of two"
(slices 1 "01234") (assertEqual (Ok [ [ 9, 7 ], [ 7, 8 ], [ 8, 6 ], [ 6, 7 ], [ 7, 5 ], [ 5, 6 ], [ 6, 4 ] ])
) (slices 2 "97867564")
, test )
"slices of two" , test "slices of three"
(assertEqual (assertEqual (Ok [ [ 9, 7, 8 ], [ 7, 8, 6 ], [ 8, 6, 7 ], [ 6, 7, 5 ], [ 7, 5, 6 ], [ 5, 6, 4 ] ])
(Ok [ [ 9, 7 ], [ 7, 8 ], [ 8, 6 ], [ 6, 7 ], [ 7, 5 ], [ 5, 6 ], [ 6, 4 ] ]) (slices 3 "97867564")
(slices 2 "97867564") )
) , test "slices of four"
, test (assertEqual (Ok [ [ 0, 1, 2, 3 ], [ 1, 2, 3, 4 ] ])
"slices of three" (slices 4 "01234")
(assertEqual )
(Ok [ [ 9, 7, 8 ], [ 7, 8, 6 ], [ 8, 6, 7 ], [ 6, 7, 5 ], [ 7, 5, 6 ], [ 5, 6, 4 ] ]) , test "slices of five"
(slices 3 "97867564") (assertEqual (Ok [ [ 0, 1, 2, 3, 4 ] ])
) (slices 5 "01234")
, test )
"slices of four" , test "overly long slice"
(assertEqual (assertEqual (Ok [])
(Ok [ [ 0, 1, 2, 3 ], [ 1, 2, 3, 4 ] ]) (slices 4 "012")
(slices 4 "01234") )
) , test "overly short slice"
, test (assertEqual (Err ("Invalid size: 0"))
"slices of five" (slices 0 "01234")
(assertEqual )
(Ok [ [ 0, 1, 2, 3, 4 ] ]) , test "input has non numbers"
(slices 5 "01234") (assertEqual (Err "could not convert string 'a' to an Int")
) (slices 2 "0123abc")
, test )
"overly long slice" ]
(assertEqual
(Ok [])
(slices 4 "012")
)
, test
"overly short slice"
(assertEqual
(Err ("Invalid size: 0"))
(slices 0 "01234")
)
, test
"input has non numbers"
(assertEqual
(Err "could not convert string 'a' to an Int")
(slices 2 "0123abc")
)
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -2,49 +2,49 @@ module SpaceAge exposing (..)
type Planet type Planet
= Mercury = Mercury
| Venus | Venus
| Earth | Earth
| Mars | Mars
| Jupiter | Jupiter
| Saturn | Saturn
| Uranus | Uranus
| Neptune | Neptune
earthYearInSeconds = earthYearInSeconds =
365.25 * 24 * 60 * 60 365.25 * 24 * 60 * 60
ageOn : Planet -> Float -> Float ageOn : Planet -> Float -> Float
ageOn planet seconds = ageOn planet seconds =
seconds / (secondsPerYear planet) seconds / (secondsPerYear planet)
secondsPerYear : Planet -> Float secondsPerYear : Planet -> Float
secondsPerYear planet = secondsPerYear planet =
earthYearInSeconds earthYearInSeconds
* case planet of * case planet of
Mercury -> Mercury ->
0.2408467 0.2408467
Venus -> Venus ->
0.61519726 0.61519726
Earth -> Earth ->
1 1
Mars -> Mars ->
1.8808158 1.8808158
Jupiter -> Jupiter ->
11.862615 11.862615
Saturn -> Saturn ->
29.447498 29.447498
Uranus -> Uranus ->
84.016846 84.016846
Neptune -> Neptune ->
164.79132 164.79132

View file

@ -6,35 +6,26 @@ import SpaceAge exposing (Planet(..), ageOn)
tests : Test tests : Test
tests = tests =
suite suite "SpaceAge"
"SpaceAge" [ test "age in earth years"
[ test (assertEqual 32 (round (ageOn Earth 1000000000)))
"age in earth years" , test "age in mercury years"
(assertEqual 32 (round (ageOn Earth 1000000000))) (assertEqual 281 (round (ageOn Mercury 2134835688)))
, test , test "age in venus years"
"age in mercury years" (assertEqual 10 (round (ageOn Venus 189839836)))
(assertEqual 281 (round (ageOn Mercury 2134835688))) , test "age on mars"
, test (assertEqual 39 (round (ageOn Mars 2329871239)))
"age in venus years" , test "age on jupiter"
(assertEqual 10 (round (ageOn Venus 189839836))) (assertEqual 2 (round (ageOn Jupiter 901876382)))
, test , test "age on saturn"
"age on mars" (assertEqual 3 (round (ageOn Saturn 3000000000)))
(assertEqual 39 (round (ageOn Mars 2329871239))) , test "age on uranus"
, test (assertEqual 1 (round (ageOn Uranus 3210123456)))
"age on jupiter" , test "age on neptune"
(assertEqual 2 (round (ageOn Jupiter 901876382))) (assertEqual 2 (round (ageOn Neptune 8210123456)))
, test ]
"age on saturn"
(assertEqual 3 (round (ageOn Saturn 3000000000)))
, test
"age on uranus"
(assertEqual 1 (round (ageOn Uranus 3210123456)))
, test
"age on neptune"
(assertEqual 2 (round (ageOn Neptune 8210123456)))
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -5,17 +5,17 @@ import List
keep : (a -> Bool) -> List a -> List a keep : (a -> Bool) -> List a -> List a
keep predicate list = keep predicate list =
List.foldr (consIf predicate) [] list List.foldr (consIf predicate) [] list
discard : (a -> Bool) -> List a -> List a discard : (a -> Bool) -> List a -> List a
discard predicate list = discard predicate list =
List.foldr (consIf (\v -> not <| predicate v)) [] list List.foldr (consIf (\v -> not <| predicate v)) [] list
consIf : (a -> Bool) -> a -> List a -> List a consIf : (a -> Bool) -> a -> List a -> List a
consIf predicate value list = consIf predicate value list =
if predicate value then if predicate value then
value :: list value :: list
else else
list list

View file

@ -7,103 +7,78 @@ import String
even : Int -> Bool even : Int -> Bool
even number = even number =
number % 2 == 0 number % 2 == 0
odd : Int -> Bool odd : Int -> Bool
odd number = odd number =
number % 2 == 1 number % 2 == 1
isFirstLetter : String -> String -> Bool isFirstLetter : String -> String -> Bool
isFirstLetter letter word = isFirstLetter letter word =
(String.left 1 word) == letter (String.left 1 word) == letter
lessThanTen : number -> Bool lessThanTen : number -> Bool
lessThanTen num = lessThanTen num =
num < 10 num < 10
tests : Test tests : Test
tests = tests =
suite suite "Strain"
"Strain" [ test "empty keep"
[ test (assertEqual []
"empty keep" (keep lessThanTen [])
(assertEqual )
[] , test "keep everything"
(keep lessThanTen []) (assertEqual [ 1, 2, 3 ]
) (keep lessThanTen [ 1, 2, 3 ])
, test )
"keep everything" , test "keep first and last"
(assertEqual (assertEqual [ 1, 3 ]
[ 1, 2, 3 ] (keep odd [ 1, 2, 3 ])
(keep lessThanTen [ 1, 2, 3 ]) )
) , test "keep nothing"
, test (assertEqual []
"keep first and last" (keep even [ 1, 3, 5, 7 ])
(assertEqual )
[ 1, 3 ] , test "keep neither first nor last"
(keep odd [ 1, 2, 3 ]) (assertEqual [ 2 ]
) (keep even [ 1, 2, 3 ])
, test )
"keep nothing" , test "keep strings"
(assertEqual (assertEqual [ "zebra", "zombies", "zealot" ]
[] (keep (isFirstLetter "z") [ "apple", "zebra", "banana", "zombies", "cherimoya", "zealot" ])
(keep even [ 1, 3, 5, 7 ]) )
) , test "empty discard"
, test (assertEqual []
"keep neither first nor last" (discard lessThanTen [])
(assertEqual )
[ 2 ] , test "discard everything"
(keep even [ 1, 2, 3 ]) (assertEqual []
) (discard lessThanTen [ 1, 2, 3 ])
, test )
"keep strings" , test "discard first and last"
(assertEqual (assertEqual [ 2 ]
[ "zebra", "zombies", "zealot" ] (discard odd [ 1, 2, 3 ])
(keep (isFirstLetter "z") [ "apple", "zebra", "banana", "zombies", "cherimoya", "zealot" ]) )
) , test "discard nothing"
, test (assertEqual [ 1, 3, 5, 7 ]
"empty discard" (discard even [ 1, 3, 5, 7 ])
(assertEqual )
[] , test "discard neither first nor last"
(discard lessThanTen []) (assertEqual [ 1, 3 ]
) (discard even [ 1, 2, 3 ])
, test )
"discard everything" , test "discard strings"
(assertEqual (assertEqual [ "apple", "banana", "cherimoya" ]
[] (discard (isFirstLetter "z") [ "apple", "zebra", "banana", "zombies", "cherimoya", "zealot" ])
(discard lessThanTen [ 1, 2, 3 ]) )
) ]
, test
"discard first and last"
(assertEqual
[ 2 ]
(discard odd [ 1, 2, 3 ])
)
, test
"discard nothing"
(assertEqual
[ 1, 3, 5, 7 ]
(discard even [ 1, 3, 5, 7 ])
)
, test
"discard neither first nor last"
(assertEqual
[ 1, 3 ]
(discard even [ 1, 2, 3 ])
)
, test
"discard strings"
(assertEqual
[ "apple", "banana", "cherimoya" ]
(discard (isFirstLetter "z") [ "apple", "zebra", "banana", "zombies", "cherimoya", "zealot" ])
)
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -3,37 +3,37 @@ module Sublist exposing (..)
version : Int version : Int
version = version =
2 2
type ListComparison type ListComparison
= Equal = Equal
| Superlist | Superlist
| Sublist | Sublist
| Unequal | Unequal
sublist : List a -> List a -> ListComparison sublist : List a -> List a -> ListComparison
sublist alist blist = sublist alist blist =
if alist == blist then if alist == blist then
Equal Equal
else if inList alist blist then else if inList alist blist then
Superlist Superlist
else if inList blist alist then else if inList blist alist then
Sublist Sublist
else else
Unequal Unequal
inList : List a -> List a -> Bool inList : List a -> List a -> Bool
inList alist blist = inList alist blist =
let let
getLastInList sublist = getLastInList sublist =
Maybe.withDefault [] (List.tail sublist) Maybe.withDefault [] (List.tail sublist)
in in
if (List.length alist) < (List.length blist) then if (List.length alist) < (List.length blist) then
False False
else if (List.take (List.length blist) alist) == blist then else if (List.take (List.length blist) alist) == blist then
True True
else else
inList (getLastInList alist) blist inList (getLastInList alist) blist

View file

@ -6,68 +6,48 @@ import Sublist exposing (version, sublist, ListComparison(..))
tests : Test tests : Test
tests = tests =
suite suite "Sublist"
"Sublist" [ test "the solution is for the correct version of the test"
[ test (assertEqual 2 version)
"the solution is for the correct version of the test" , test "empty equals empty"
(assertEqual 2 version) (assertEqual Equal (sublist [] []))
, test , test "empty is a sublist of anything"
"empty equals empty" (assertEqual Sublist (sublist [] [ 1, 2 ]))
(assertEqual Equal (sublist [] [])) , test "anything is a superlist of empty"
, test (assertEqual Superlist (sublist [ 1, 2 ] []))
"empty is a sublist of anything" , test "1 is not 2"
(assertEqual Sublist (sublist [] [ 1, 2 ])) (assertEqual Unequal (sublist [ 1 ] [ 2 ]))
, test , test "compare larger equal lists"
"anything is a superlist of empty" (assertEqual Equal (sublist [ 1, 1, 1 ] [ 1, 1, 1 ]))
(assertEqual Superlist (sublist [ 1, 2 ] [])) , test "sublist at start"
, test (assertEqual Sublist (sublist [ 1, 2, 3 ] [ 1, 2, 3, 4, 5 ]))
"1 is not 2" , test "sublist in the middle"
(assertEqual Unequal (sublist [ 1 ] [ 2 ])) (assertEqual Sublist (sublist [ 4, 3, 2 ] [ 5, 4, 3, 2, 1 ]))
, test , test "sublist at end"
"compare larger equal lists" (assertEqual Sublist (sublist [ 3, 4, 5 ] [ 1, 2, 3, 4, 5 ]))
(assertEqual Equal (sublist [ 1, 1, 1 ] [ 1, 1, 1 ])) , test "partially matching sublist at start"
, test (assertEqual Sublist (sublist [ 1, 1, 2 ] [ 1, 1, 1, 2 ]))
"sublist at start" , test "sublist early in huge list"
(assertEqual Sublist (sublist [ 1, 2, 3 ] [ 1, 2, 3, 4, 5 ])) (assertEqual Sublist (sublist [ 3, 4, 5 ] [1..100000]))
, test , test "huge sublist not in list"
"sublist in the middle" (assertEqual Unequal (sublist [10..5001] [1..5000]))
(assertEqual Sublist (sublist [ 4, 3, 2 ] [ 5, 4, 3, 2, 1 ])) , test "superlist at start"
, test (assertEqual Superlist (sublist [ 1, 2, 3, 4, 5 ] [ 1, 2, 3 ]))
"sublist at end" , test "superlist in middle"
(assertEqual Sublist (sublist [ 3, 4, 5 ] [ 1, 2, 3, 4, 5 ])) (assertEqual Superlist (sublist [ 5, 4, 3, 2, 1 ] [ 4, 3, 2 ]))
, test , test "superlist at end"
"partially matching sublist at start" (assertEqual Superlist (sublist [ 1, 2, 3, 4, 5 ] [ 3, 4, 5 ]))
(assertEqual Sublist (sublist [ 1, 1, 2 ] [ 1, 1, 1, 2 ])) , test "partially matching superlist at start"
, test (assertEqual Superlist (sublist [ 1, 1, 1, 2 ] [ 1, 1, 2 ]))
"sublist early in huge list" , test "superlist early in huge list"
(assertEqual Sublist (sublist [ 3, 4, 5 ] [1..100000])) (assertEqual Superlist (sublist [1..100000] [ 3, 4, 5 ]))
, test , test "recurring values sublist"
"huge sublist not in list" (assertEqual Sublist (sublist [ 1, 2, 1, 2, 3 ] [ 1, 2, 3, 1, 2, 1, 2, 3, 2, 1 ]))
(assertEqual Unequal (sublist [10..5001] [1..5000])) , test "recurring values unequal"
, test (assertEqual Unequal (sublist [ 1, 2, 1, 2, 3 ] [ 1, 2, 3, 1, 2, 3, 2, 3, 2, 1 ]))
"superlist at start" ]
(assertEqual Superlist (sublist [ 1, 2, 3, 4, 5 ] [ 1, 2, 3 ]))
, test
"superlist in middle"
(assertEqual Superlist (sublist [ 5, 4, 3, 2, 1 ] [ 4, 3, 2 ]))
, test
"superlist at end"
(assertEqual Superlist (sublist [ 1, 2, 3, 4, 5 ] [ 3, 4, 5 ]))
, test
"partially matching superlist at start"
(assertEqual Superlist (sublist [ 1, 1, 1, 2 ] [ 1, 1, 2 ]))
, test
"superlist early in huge list"
(assertEqual Superlist (sublist [1..100000] [ 3, 4, 5 ]))
, test
"recurring values sublist"
(assertEqual Sublist (sublist [ 1, 2, 1, 2, 3 ] [ 1, 2, 3, 1, 2, 1, 2, 3, 2, 1 ]))
, test
"recurring values unequal"
(assertEqual Unequal (sublist [ 1, 2, 1, 2, 3 ] [ 1, 2, 3, 1, 2, 3, 2, 3, 2, 1 ]))
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -3,9 +3,9 @@ module SumOfMultiples exposing (..)
sumOfMultiples : List Int -> Int -> Int sumOfMultiples : List Int -> Int -> Int
sumOfMultiples multiples limit = sumOfMultiples multiples limit =
List.sum (List.filter (inMultiples multiples) [1..(limit - 1)]) List.sum (List.filter (inMultiples multiples) [1..(limit - 1)])
inMultiples : List Int -> Int -> Bool inMultiples : List Int -> Int -> Bool
inMultiples multiples candidate = inMultiples multiples candidate =
List.any (\factor -> candidate % factor == 0) multiples List.any (\factor -> candidate % factor == 0) multiples

View file

@ -6,17 +6,16 @@ import SumOfMultiples exposing (sumOfMultiples)
tests : Test tests : Test
tests = tests =
suite suite "Sum Of Multiples"
"Sum Of Multiples" [ test "[3, 5] 15" (assertEqual 45 (sumOfMultiples [ 3, 5 ] 15))
[ test "[3, 5] 15" (assertEqual 45 (sumOfMultiples [ 3, 5 ] 15)) , test "[7, 13, 17] 20" (assertEqual 51 (sumOfMultiples [ 7, 13, 17 ] 20))
, test "[7, 13, 17] 20" (assertEqual 51 (sumOfMultiples [ 7, 13, 17 ] 20)) , test "[4, 6] 15" (assertEqual 30 (sumOfMultiples [ 4, 6 ] 15))
, test "[4, 6] 15" (assertEqual 30 (sumOfMultiples [ 4, 6 ] 15)) , test "[5, 6, 8] 150" (assertEqual 4419 (sumOfMultiples [ 5, 6, 8 ] 150))
, test "[5, 6, 8] 150" (assertEqual 4419 (sumOfMultiples [ 5, 6, 8 ] 150)) , test "[43, 47] 10000" (assertEqual 2203160 (sumOfMultiples [ 43, 47 ] 10000))
, test "[43, 47] 10000" (assertEqual 2203160 (sumOfMultiples [ 43, 47 ] 10000)) , test "[5, 25] 51" (assertEqual 275 (sumOfMultiples [ 5, 25 ] 51))
, test "[5, 25] 51" (assertEqual 275 (sumOfMultiples [ 5, 25 ] 51)) ]
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -5,17 +5,17 @@ import Set
triangleKind : number -> number -> number -> Result String String triangleKind : number -> number -> number -> Result String String
triangleKind x y z = triangleKind x y z =
if x <= 0 || y <= 0 || z <= 0 then if x <= 0 || y <= 0 || z <= 0 then
Err "Invalid lengths" Err "Invalid lengths"
else if x + y <= z || x + z <= y || y + z <= x then else if x + y <= z || x + z <= y || y + z <= x then
Err "Violates inequality" Err "Violates inequality"
else else
case Set.size (Set.fromList [ x, y, z ]) of case Set.size (Set.fromList [ x, y, z ]) of
1 -> 1 ->
Ok "equilateral" Ok "equilateral"
2 -> 2 ->
Ok "isosceles" Ok "isosceles"
_ -> _ ->
Ok "scalene" Ok "scalene"

View file

@ -6,56 +6,40 @@ import Triangle exposing (triangleKind)
tests : Test tests : Test
tests = tests =
suite suite "triangleKind"
"triangleKind" [ test "equilateral triangles have equal sides"
[ test (assertEqual (Ok "equilateral") (triangleKind 2 2 2))
"equilateral triangles have equal sides" , test "larger equilateral triangles also have equal sides"
(assertEqual (Ok "equilateral") (triangleKind 2 2 2)) (assertEqual (Ok "equilateral") (triangleKind 10 10 10))
, test , test "isosceles triangles have last two sides equal"
"larger equilateral triangles also have equal sides" (assertEqual (Ok "isosceles") (triangleKind 3 4 4))
(assertEqual (Ok "equilateral") (triangleKind 10 10 10)) , test "isosceles triangles have first and last sides equal"
, test (assertEqual (Ok "isosceles") (triangleKind 4 3 4))
"isosceles triangles have last two sides equal" , test "isosceles triangles have two first sides equal"
(assertEqual (Ok "isosceles") (triangleKind 3 4 4)) (assertEqual (Ok "isosceles") (triangleKind 4 4 3))
, test , test "isosceles triangles have in fact exactly two sides equal"
"isosceles triangles have first and last sides equal" (assertEqual (Ok "isosceles") (triangleKind 10 10 2))
(assertEqual (Ok "isosceles") (triangleKind 4 3 4)) , test "scalene triangles have no equal sides"
, test (assertEqual (Ok "scalene") (triangleKind 3 4 5))
"isosceles triangles have two first sides equal" , test "scalene triangles have no equal sides at a larger scale too"
(assertEqual (Ok "isosceles") (triangleKind 4 4 3)) (assertEqual (Ok "scalene") (triangleKind 10 11 12))
, test , test "scalene triangles have no equal sides at a larger scale too 2"
"isosceles triangles have in fact exactly two sides equal" (assertEqual (Ok "scalene") (triangleKind 5 4 2))
(assertEqual (Ok "isosceles") (triangleKind 10 10 2)) , test "very small triangles are legal"
, test (assertEqual (Ok "scalene") (triangleKind 0.4 0.6 0.3))
"scalene triangles have no equal sides" , test "triangles with no size are illegal"
(assertEqual (Ok "scalene") (triangleKind 3 4 5)) (assertEqual (Err "Invalid lengths") (triangleKind 0 0 0))
, test , test "triangles with negative sides are illegal"
"scalene triangles have no equal sides at a larger scale too" (assertEqual (Err "Invalid lengths") (triangleKind 3 4 -5))
(assertEqual (Ok "scalene") (triangleKind 10 11 12)) , test "triangles violating triangle inequality are illegal 1"
, test (assertEqual (Err "Violates inequality") (triangleKind 1 1 3))
"scalene triangles have no equal sides at a larger scale too 2" , test "triangles violating triangle inequality are illegal 2"
(assertEqual (Ok "scalene") (triangleKind 5 4 2)) (assertEqual (Err "Violates inequality") (triangleKind 2 4 2))
, test , test "triangles violating triangle inequality are illegal 3"
"very small triangles are legal" (assertEqual (Err "Violates inequality") (triangleKind 7 3 2))
(assertEqual (Ok "scalene") (triangleKind 0.4 0.6 0.3)) ]
, test
"triangles with no size are illegal"
(assertEqual (Err "Invalid lengths") (triangleKind 0 0 0))
, test
"triangles with negative sides are illegal"
(assertEqual (Err "Invalid lengths") (triangleKind 3 4 -5))
, test
"triangles violating triangle inequality are illegal 1"
(assertEqual (Err "Violates inequality") (triangleKind 1 1 3))
, test
"triangles violating triangle inequality are illegal 2"
(assertEqual (Err "Violates inequality") (triangleKind 2 4 2))
, test
"triangles violating triangle inequality are illegal 3"
(assertEqual (Err "Violates inequality") (triangleKind 7 3 2))
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests

View file

@ -7,18 +7,18 @@ import Regex
wordCount : String -> Dict String Int wordCount : String -> Dict String Int
wordCount sentence = wordCount sentence =
sentence sentence
|> String.toLower |> String.toLower
|> depunctuate |> depunctuate
|> String.words |> String.words
|> List.foldl (\w d -> Dict.update w incrMaybe d) Dict.empty |> List.foldl (\w d -> Dict.update w incrMaybe d) Dict.empty
depunctuate : String -> String depunctuate : String -> String
depunctuate = depunctuate =
Regex.replace Regex.All (Regex.regex "[^a-z0-9 ]") (\_ -> "") Regex.replace Regex.All (Regex.regex "[^a-z0-9 ]") (\_ -> "")
incrMaybe : Maybe Int -> Maybe Int incrMaybe : Maybe Int -> Maybe Int
incrMaybe maybe = incrMaybe maybe =
(Maybe.withDefault 0 maybe) + 1 |> Just (Maybe.withDefault 0 maybe) + 1 |> Just

View file

@ -7,47 +7,34 @@ import WordCount exposing (wordCount)
tests : Test tests : Test
tests = tests =
suite suite "Word Count"
"Word Count" [ test "count one word"
[ test (assertEqual [ ( "word", 1 ) ]
"count one word" (wordCount "word" |> Dict.toList)
(assertEqual )
[ ( "word", 1 ) ] , test "count one of each word"
(wordCount "word" |> Dict.toList) (assertEqual [ ( "each", 1 ), ( "of", 1 ), ( "one", 1 ) ]
) (wordCount "one of each" |> Dict.toList)
, test )
"count one of each word" , test "multiple occurrences of a word"
(assertEqual (assertEqual [ ( "blue", 1 ), ( "fish", 4 ), ( "one", 1 ), ( "red", 1 ), ( "two", 1 ) ]
[ ( "each", 1 ), ( "of", 1 ), ( "one", 1 ) ] (wordCount "one fish two fish red fish blue fish" |> Dict.toList)
(wordCount "one of each" |> Dict.toList) )
) , test "ignore punctuation"
, test (assertEqual [ ( "as", 1 ), ( "car", 1 ), ( "carpet", 1 ), ( "java", 1 ), ( "javascript", 1 ) ]
"multiple occurrences of a word" (wordCount "car : carpet as java : javascript!!&@$%^&" |> Dict.toList)
(assertEqual )
[ ( "blue", 1 ), ( "fish", 4 ), ( "one", 1 ), ( "red", 1 ), ( "two", 1 ) ] , test "include numbers"
(wordCount "one fish two fish red fish blue fish" |> Dict.toList) (assertEqual [ ( "1", 1 ), ( "2", 1 ), ( "testing", 2 ) ]
) (wordCount "testing, 1, 2 testing" |> Dict.toList)
, test )
"ignore punctuation" , test "normalize case"
(assertEqual (assertEqual [ ( "go", 3 ), ( "stop", 2 ) ]
[ ( "as", 1 ), ( "car", 1 ), ( "carpet", 1 ), ( "java", 1 ), ( "javascript", 1 ) ] (wordCount "go Go GO Stop stop" |> Dict.toList)
(wordCount "car : carpet as java : javascript!!&@$%^&" |> Dict.toList) )
) ]
, test
"include numbers"
(assertEqual
[ ( "1", 1 ), ( "2", 1 ), ( "testing", 2 ) ]
(wordCount "testing, 1, 2 testing" |> Dict.toList)
)
, test
"normalize case"
(assertEqual
[ ( "go", 3 ), ( "stop", 2 ) ]
(wordCount "go Go GO Stop stop" |> Dict.toList)
)
]
main : Program Never main : Program Never
main = main =
runSuite tests runSuite tests