Created
November 6, 2019 22:20
-
-
Save tjstankus/1de98b2a1e3b6e150b3b30ab982e3e34 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule CountdownSong do | |
def song(%{upper: upper, lower: lower}, verse_template) do | |
verses(upper, lower, verse_template) | |
end | |
def verses(upper, lower, verse_template) do | |
upper..lower | |
|> Enum.map(fn n -> verse(n, verse_template) end) | |
|> Enum.join("\n") | |
end | |
def verse(num, verse_template) do | |
verse_template.lyrics(num) | |
end | |
end | |
defmodule Bottles do | |
defstruct upper: 99, lower: 0 | |
end | |
defmodule VerseTemplate do | |
@callback lyrics(integer) :: String.t() | |
end | |
defmodule BottleVerse do | |
@behaviour VerseTemplate | |
@impl VerseTemplate | |
def lyrics(num) do | |
"#{bottle_number(num) |> String.capitalize()} of beer on the wall, " <> | |
"#{bottle_number(num)} of beer.\n" <> | |
"#{action(num)}, " <> | |
"#{successor(num) |> bottle_number()} of beer on the wall.\n" | |
end | |
def bottle_number(num) do | |
"#{amount(num)} #{container(num)}" | |
end | |
defp container(6), do: "six-pack" | |
defp container(1), do: "bottle" | |
defp container(_), do: "bottles" | |
defp pronoun(1), do: "it" | |
defp pronoun(_), do: "one" | |
defp amount(6), do: "1" | |
defp amount(0), do: "no more" | |
defp amount(num), do: "#{num}" | |
defp action(0), do: "Go to the store and buy some more" | |
defp action(num), do: "Take #{pronoun(num)} down and pass it around" | |
defp successor(0), do: 99 | |
defp successor(num), do: num - 1 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment