Avatar of paulfioravanti

paulfioravanti's solution

to Twelve Days in the Elm Track

Published at Jun 20 2019 · 0 comments
Instructions
Test suite
Solution

Output the lyrics to 'The Twelve Days of Christmas'.

On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree.

On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree.

On the third day of Christmas my true love gave to me: three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.

On the fourth day of Christmas my true love gave to me: four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.

On the fifth day of Christmas my true love gave to me: five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.

On the sixth day of Christmas my true love gave to me: six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.

On the seventh day of Christmas my true love gave to me: seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.

On the eighth day of Christmas my true love gave to me: eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.

On the ninth day of Christmas my true love gave to me: nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.

On the tenth day of Christmas my true love gave to me: ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.

On the eleventh day of Christmas my true love gave to me: eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.

On the twelfth day of Christmas my true love gave to me: twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.

Elm Installation

Refer to the Installing Elm page for information about installing elm.

Writing the Code

The first time you start an exercise, you'll need to ensure you have the appropriate dependencies installed. Thankfully, Elm makes that easy for you and will install dependencies when you try to run tests or build the code.

Execute the tests with:

$ elm-test

Automatically run tests again when you save changes:

$ elm-test --watch

As you work your way through the test suite, be sure to remove the skip <| calls from each test until you get them all passing!

Source

Wikipedia http://en.wikipedia.org/wiki/The_Twelve_Days_of_Christmas_(song)

Submitting Incomplete Solutions

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

Tests.elm

module Tests exposing (tests)

import Expect
import Test exposing (..)
import TwelveDays


tests : Test
tests =
    describe "Twelve Days"
        [ test "first day a partridge in a pear tree" <|
            \() ->
                Expect.equal
                    [ "On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree."
                    ]
                    (TwelveDays.recite 1 1)
        , skip <|
            test "second day two turtle doves" <|
                \() ->
                    Expect.equal
                        [ "On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree."
                        ]
                        (TwelveDays.recite 2 2)
        , skip <|
            test "third day three french hens" <|
                \() ->
                    Expect.equal
                        [ "On the third day of Christmas my true love gave to me: three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        ]
                        (TwelveDays.recite 3 3)
        , skip <|
            test "fourth day four calling birds" <|
                \() ->
                    Expect.equal
                        [ "On the fourth day of Christmas my true love gave to me: four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        ]
                        (TwelveDays.recite 4 4)
        , skip <|
            test "fifth day five gold rings" <|
                \() ->
                    Expect.equal
                        [ "On the fifth day of Christmas my true love gave to me: five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        ]
                        (TwelveDays.recite 5 5)
        , skip <|
            test "sixth day six geese-a-laying" <|
                \() ->
                    Expect.equal
                        [ "On the sixth day of Christmas my true love gave to me: six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        ]
                        (TwelveDays.recite 6 6)
        , skip <|
            test "seventh day seven swans-a-swimming" <|
                \() ->
                    Expect.equal
                        [ "On the seventh day of Christmas my true love gave to me: seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        ]
                        (TwelveDays.recite 7 7)
        , skip <|
            test "eighth day eight maids-a-milking" <|
                \() ->
                    Expect.equal
                        [ "On the eighth day of Christmas my true love gave to me: eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        ]
                        (TwelveDays.recite 8 8)
        , skip <|
            test "ninth day nine ladies dancing" <|
                \() ->
                    Expect.equal
                        [ "On the ninth day of Christmas my true love gave to me: nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        ]
                        (TwelveDays.recite 9 9)
        , skip <|
            test "tenth day ten lords-a-leaping" <|
                \() ->
                    Expect.equal
                        [ "On the tenth day of Christmas my true love gave to me: ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        ]
                        (TwelveDays.recite 10 10)
        , skip <|
            test "eleventh day eleven pipers piping" <|
                \() ->
                    Expect.equal
                        [ "On the eleventh day of Christmas my true love gave to me: eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        ]
                        (TwelveDays.recite 11 11)
        , skip <|
            test "twelfth day twelve drummers drumming" <|
                \() ->
                    Expect.equal
                        [ "On the twelfth day of Christmas my true love gave to me: twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        ]
                        (TwelveDays.recite 12 12)
        , skip <|
            test "recites first three verses of the song" <|
                \() ->
                    Expect.equal
                        [ "On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree."
                        , "On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree."
                        , "On the third day of Christmas my true love gave to me: three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        ]
                        (TwelveDays.recite 1 3)
        , skip <|
            test "recites three verses from the middle of the song" <|
                \() ->
                    Expect.equal
                        [ "On the fourth day of Christmas my true love gave to me: four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        , "On the fifth day of Christmas my true love gave to me: five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        , "On the sixth day of Christmas my true love gave to me: six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        ]
                        (TwelveDays.recite 4 6)
        , skip <|
            test "recites the whole song" <|
                \() ->
                    Expect.equal
                        [ "On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree."
                        , "On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree."
                        , "On the third day of Christmas my true love gave to me: three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        , "On the fourth day of Christmas my true love gave to me: four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        , "On the fifth day of Christmas my true love gave to me: five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        , "On the sixth day of Christmas my true love gave to me: six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        , "On the seventh day of Christmas my true love gave to me: seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        , "On the eighth day of Christmas my true love gave to me: eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        , "On the ninth day of Christmas my true love gave to me: nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        , "On the tenth day of Christmas my true love gave to me: ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        , "On the eleventh day of Christmas my true love gave to me: eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        , "On the twelfth day of Christmas my true love gave to me: twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."
                        ]
                        (TwelveDays.recite 1 12)
        ]
module TwelveDays exposing (recite)

import Array
import Dict exposing (Dict)


recite : Int -> Int -> List String
recite start stop =
    List.range start stop
        |> List.map verse



-- PRIVATE


verse : Int -> String
verse number =
    let
        index =
            number - 1

        ordinal =
            valueAtIndex index ordinals

        declarationOfReceipt =
            "On the "
                ++ ordinal
                ++ " day of Christmas my true love gave to me: "

        amount =
            cardinalFromOrdinal ordinal

        currentGift =
            valueAtIndex index gifts

        extraGifts =
            calculateExtraGifts index
    in
    declarationOfReceipt ++ amount ++ currentGift ++ extraGifts ++ "."


valueAtIndex : Int -> List String -> String
valueAtIndex index list =
    list
        |> Array.fromList
        |> Array.get index
        |> Maybe.withDefault "first"


cardinalFromOrdinal : String -> String
cardinalFromOrdinal ordinal =
    let
        removeOrdinalEnding ord =
            ord
                |> String.replace "th" ""
    in
    cardinals
        |> Dict.get ordinal
        |> Maybe.withDefault (removeOrdinalEnding ordinal)


calculateExtraGifts : Int -> String
calculateExtraGifts index =
    let
        giftsForEachDayOfChristmas =
            List.map2 Tuple.pair ordinals gifts
    in
    giftsForEachDayOfChristmas
        |> List.take index
        |> List.foldl addGift []
        |> String.join ""


addGift : ( String, String ) -> List String -> List String
addGift ( ordinal, gift ) acc =
    let
        amount =
            cardinalFromOrdinal ordinal
    in
    case acc of
        [] ->
            [ ", and " ++ amount ++ gift ]

        _ ->
            (", " ++ amount ++ gift) :: acc


cardinals : Dict String String
cardinals =
    Dict.fromList
        [ ( "first", "a" )
        , ( "second", "two" )
        , ( "third", "three" )
        , ( "fifth", "five" )
        , ( "eighth", "eight" )
        , ( "ninth", "nine" )
        , ( "twelfth", "twelve" )
        ]


ordinals : List String
ordinals =
    [ "first"
    , "second"
    , "third"
    , "fourth"
    , "fifth"
    , "sixth"
    , "seventh"
    , "eighth"
    , "ninth"
    , "tenth"
    , "eleventh"
    , "twelfth"
    ]


gifts : List String
gifts =
    [ " Partridge in a Pear Tree"
    , " Turtle Doves"
    , " French Hens"
    , " Calling Birds"
    , " Gold Rings"
    , " Geese-a-Laying"
    , " Swans-a-Swimming"
    , " Maids-a-Milking"
    , " Ladies Dancing"
    , " Lords-a-Leaping"
    , " Pipers Piping"
    , " Drummers Drumming"
    ]

Community comments

Find this solution interesting? Ask the author a question to learn more.

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?