diff --git a/config.json b/config.json index c923d31b..53f9404c 100644 --- a/config.json +++ b/config.json @@ -1326,6 +1326,20 @@ ], "difficulty": 6 }, + { + "slug": "food-chain", + "name": "Food Chain", + "uuid": "40e735ba-0bc7-436e-9c5f-5a8abdf8c436", + "practices": [], + "prerequisites": [ + "strings", + "lists", + "tuples", + "pattern-matching", + "let" + ], + "difficulty": 4 + }, { "slug": "knapsack", "name": "Knapsack", diff --git a/exercises/practice/food-chain/.docs/instructions.md b/exercises/practice/food-chain/.docs/instructions.md new file mode 100644 index 00000000..125820e3 --- /dev/null +++ b/exercises/practice/food-chain/.docs/instructions.md @@ -0,0 +1,64 @@ +# Instructions + +Generate the lyrics of the song 'I Know an Old Lady Who Swallowed a Fly'. + +While you could copy/paste the lyrics, or read them from a file, this problem is much more interesting if you approach it algorithmically. + +This is a [cumulative song][cumulative-song] of unknown origin. + +This is one of many common variants. + +```text +I know an old lady who swallowed a fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a spider. +It wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a bird. +How absurd to swallow a bird! +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a cat. +Imagine that, to swallow a cat! +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a dog. +What a hog, to swallow a dog! +She swallowed the dog to catch the cat. +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a goat. +Just opened her throat and swallowed a goat! +She swallowed the goat to catch the dog. +She swallowed the dog to catch the cat. +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a cow. +I don't know how she swallowed a cow! +She swallowed the cow to catch the goat. +She swallowed the goat to catch the dog. +She swallowed the dog to catch the cat. +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a horse. +She's dead, of course! +``` + +[cumulative-song]: https://en.wikipedia.org/wiki/Cumulative_song diff --git a/exercises/practice/food-chain/.meta/config.json b/exercises/practice/food-chain/.meta/config.json new file mode 100644 index 00000000..903d35ba --- /dev/null +++ b/exercises/practice/food-chain/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "jiegillet" + ], + "files": { + "solution": [ + "src/FoodChain.elm" + ], + "test": [ + "tests/Tests.elm" + ], + "example": [ + ".meta/src/FoodChain.example.elm" + ] + }, + "blurb": "Generate the lyrics of the song 'I Know an Old Lady Who Swallowed a Fly'.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/There_Was_an_Old_Lady_Who_Swallowed_a_Fly" +} diff --git a/exercises/practice/food-chain/.meta/src/FoodChain.example.elm b/exercises/practice/food-chain/.meta/src/FoodChain.example.elm new file mode 100644 index 00000000..382ac2aa --- /dev/null +++ b/exercises/practice/food-chain/.meta/src/FoodChain.example.elm @@ -0,0 +1,63 @@ +module FoodChain exposing (recite) + + +recite : Int -> Int -> String +recite startVerse endVerse = + List.range startVerse endVerse + |> List.map (verseLines >> String.join "\n") + |> String.join "\n\n" + + +songData : List ( String, String ) +songData = + [ ( "horse", "She's dead, of course!" ) + , ( "cow", "I don't know how she swallowed a cow!" ) + , ( "goat", "Just opened her throat and swallowed a goat!" ) + , ( "dog", "What a hog, to swallow a dog!" ) + , ( "cat", "Imagine that, to swallow a cat!" ) + , ( "bird", "How absurd to swallow a bird!" ) + , ( "spider", "It wriggled and jiggled and tickled inside her." ) + , ( "fly", "I don't know why she swallowed the fly. Perhaps she'll die." ) + ] + + +numberOfVerses : Int +numberOfVerses = + 8 + + +verseLines : Int -> List String +verseLines n = + let + line animal = + "I know an old lady who swallowed a " ++ animal ++ "." + in + case List.drop (numberOfVerses - n) songData of + [] -> + [] + + ( "horse" as animal, phrase ) :: _ -> + [ line animal, phrase ] + + ( animal, phrase ) :: rest -> + line animal :: phrase :: escalation animal rest + + +escalation : String -> List ( String, String ) -> List String +escalation animal remainingData = + let + line nextAnimal = + "She swallowed the " ++ animal ++ " to catch the " ++ nextAnimal ++ "." + in + case remainingData of + [] -> + [] + + [ ( lastAnimal, lastPhrase ) ] -> + [ line lastAnimal, lastPhrase ] + + ( "spider" as nextAnimal, _ ) :: rest -> + line "spider that wriggled and jiggled and tickled inside her" :: escalation nextAnimal rest + + ( nextAnimal, _ ) :: rest -> + line nextAnimal :: escalation nextAnimal rest diff --git a/exercises/practice/food-chain/.meta/tests.toml b/exercises/practice/food-chain/.meta/tests.toml new file mode 100644 index 00000000..30c5b980 --- /dev/null +++ b/exercises/practice/food-chain/.meta/tests.toml @@ -0,0 +1,40 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[751dce68-9412-496e-b6e8-855998c56166] +description = "fly" + +[6c56f861-0c5e-4907-9a9d-b2efae389379] +description = "spider" + +[3edf5f33-bef1-4e39-ae67-ca5eb79203fa] +description = "bird" + +[e866a758-e1ff-400e-9f35-f27f28cc288f] +description = "cat" + +[3f02c30e-496b-4b2a-8491-bc7e2953cafb] +description = "dog" + +[4b3fd221-01ea-46e0-825b-5734634fbc59] +description = "goat" + +[1b707da9-7001-4fac-941f-22ad9c7a65d4] +description = "cow" + +[3cb10d46-ae4e-4d2c-9296-83c9ffc04cdc] +description = "horse" + +[22b863d5-17e4-4d1e-93e4-617329a5c050] +description = "multiple verses" + +[e626b32b-745c-4101-bcbd-3b13456893db] +description = "full song" diff --git a/exercises/practice/food-chain/elm.json b/exercises/practice/food-chain/elm.json new file mode 100644 index 00000000..22c9e137 --- /dev/null +++ b/exercises/practice/food-chain/elm.json @@ -0,0 +1,29 @@ +{ + "type": "application", + "source-directories": [ + "src" + ], + "elm-version": "0.19.1", + "dependencies": { + "direct": { + "elm/core": "1.0.5", + "elm/json": "1.1.3", + "elm/parser": "1.1.0", + "elm/random": "1.0.0", + "elm/regex": "1.0.0", + "elm/time": "1.0.0" + }, + "indirect": {} + }, + "test-dependencies": { + "direct": { + "elm-explorations/test": "2.1.0", + "rtfeldman/elm-iso8601-date-strings": "1.1.4" + }, + "indirect": { + "elm/bytes": "1.0.8", + "elm/html": "1.0.0", + "elm/virtual-dom": "1.0.3" + } + } +} diff --git a/exercises/practice/food-chain/src/FoodChain.elm b/exercises/practice/food-chain/src/FoodChain.elm new file mode 100644 index 00000000..d7e58b04 --- /dev/null +++ b/exercises/practice/food-chain/src/FoodChain.elm @@ -0,0 +1,6 @@ +module FoodChain exposing (recite) + + +recite : Int -> Int -> String +recite startVerse endVerse = + Debug.todo "Please implement recite" diff --git a/exercises/practice/food-chain/tests/Tests.elm b/exercises/practice/food-chain/tests/Tests.elm new file mode 100644 index 00000000..875f1435 --- /dev/null +++ b/exercises/practice/food-chain/tests/Tests.elm @@ -0,0 +1,157 @@ +module Tests exposing (tests) + +import Expect +import FoodChain +import Test exposing (Test, describe, skip, test) + + +tests : Test +tests = + describe "FoodChain" + [ -- skip <| + test "fly" <| + \() -> + FoodChain.recite 1 1 + |> Expect.equal """I know an old lady who swallowed a fly. +I don't know why she swallowed the fly. Perhaps she'll die.""" + , skip <| + test "spider" <| + \() -> + FoodChain.recite 2 2 + |> Expect.equal """I know an old lady who swallowed a spider. +It wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die.""" + , skip <| + test "bird" <| + \() -> + FoodChain.recite 3 3 + |> Expect.equal """I know an old lady who swallowed a bird. +How absurd to swallow a bird! +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die.""" + , skip <| + test "cat" <| + \() -> + FoodChain.recite 4 4 + |> Expect.equal """I know an old lady who swallowed a cat. +Imagine that, to swallow a cat! +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die.""" + , skip <| + test "dog" <| + \() -> + FoodChain.recite 5 5 + |> Expect.equal """I know an old lady who swallowed a dog. +What a hog, to swallow a dog! +She swallowed the dog to catch the cat. +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die.""" + , skip <| + test "goat" <| + \() -> + FoodChain.recite 6 6 + |> Expect.equal """I know an old lady who swallowed a goat. +Just opened her throat and swallowed a goat! +She swallowed the goat to catch the dog. +She swallowed the dog to catch the cat. +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die.""" + , skip <| + test "cow" <| + \() -> + FoodChain.recite 7 7 + |> Expect.equal """I know an old lady who swallowed a cow. +I don't know how she swallowed a cow! +She swallowed the cow to catch the goat. +She swallowed the goat to catch the dog. +She swallowed the dog to catch the cat. +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die.""" + , skip <| + test "horse" <| + \() -> + FoodChain.recite 8 8 + |> Expect.equal """I know an old lady who swallowed a horse. +She's dead, of course!""" + , skip <| + test "multiple verses" <| + \() -> + FoodChain.recite 1 3 + |> Expect.equal """I know an old lady who swallowed a fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a spider. +It wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a bird. +How absurd to swallow a bird! +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die.""" + , skip <| + test "full song" <| + \() -> + FoodChain.recite 1 8 + |> Expect.equal """I know an old lady who swallowed a fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a spider. +It wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a bird. +How absurd to swallow a bird! +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a cat. +Imagine that, to swallow a cat! +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a dog. +What a hog, to swallow a dog! +She swallowed the dog to catch the cat. +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a goat. +Just opened her throat and swallowed a goat! +She swallowed the goat to catch the dog. +She swallowed the dog to catch the cat. +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a cow. +I don't know how she swallowed a cow! +She swallowed the cow to catch the goat. +She swallowed the goat to catch the dog. +She swallowed the dog to catch the cat. +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a horse. +She's dead, of course!""" + ]