Last active
May 23, 2017 03:19
-
-
Save damonkelley/029420d0ba7fd48db63c4a9f041b2df4 to your computer and use it in GitHub Desktop.
Change Maker in Elixir - with and without a macro
This file contains hidden or 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 ChangeMaker do | |
@coins [50, 25, 10, 5, 1] | |
def change(n) do | |
@coins | |
|> Enum.zip([0, 0, 0, 0, 0]) | |
|> Enum.into(%{}) | |
|> change(n) | |
end | |
defp change(values, 0), do: values | |
for coin <- @coins do | |
defp change(values, n) when n >= unquote(coin) do | |
change(increment_for(values, unquote(coin)), n - unquote(coin)) | |
end | |
end | |
defp increment_for(values, coin) do | |
Map.update!(values, coin, &(&1 + 1)) | |
end | |
end |
This file contains hidden or 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 ChangeMakerTest do | |
use ExUnit.Case | |
doctest ChangeMaker | |
test "it gives no change" do | |
assert ChangeMaker.change(0) == %{1 => 0, 5 => 0, 10 => 0, 25 => 0, 50 => 0} | |
end | |
test "it gives back 1 penny" do | |
assert ChangeMaker.change(1) == %{1 => 1, 5 => 0, 10 => 0, 25 => 0, 50 => 0} | |
end | |
test "it gives back 2 pennies" do | |
assert ChangeMaker.change(2) == %{1 => 2, 5 => 0, 10 => 0, 25 => 0, 50 => 0} | |
end | |
test "it gives back a nickel" do | |
assert ChangeMaker.change(5) == %{1 => 0, 5 => 1, 10 => 0, 25 => 0, 50 => 0} | |
end | |
test "it gives back a nickel and a penny" do | |
assert ChangeMaker.change(6) == %{1 => 1, 5 => 1, 10 => 0, 25 => 0, 50 => 0} | |
end | |
test "it gives back a dime and and a penny" do | |
assert ChangeMaker.change(11) == %{1 => 1, 5 => 0, 10 => 1, 25 => 0, 50 => 0} | |
end | |
test "it gives back a quarter and and a nickel" do | |
assert ChangeMaker.change(30) == %{1 => 0, 5 => 1, 10 => 0, 25 => 1, 50 => 0} | |
end | |
test "it gives back a half dollar and a nickel" do | |
assert ChangeMaker.change(55) == %{1 => 0, 5 => 1, 10 => 0, 25 => 0, 50 => 1} | |
end | |
end |
This file contains hidden or 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 ChangeMaker do | |
@coins [50, 25, 10, 5, 1] | |
def change(n) do | |
@coins | |
|> Enum.zip([0, 0, 0, 0, 0]) | |
|> Enum.into(%{}) | |
|> change(n) | |
end | |
defp change(values, 0), do: values | |
defp change(values, n) when n >= 50 do | |
change(increment_for(values, 50), n - 50) | |
end | |
defp change(values, n) when n >= 25 do | |
change(increment_for(values, 25), n - 25) | |
end | |
defp change(values, n) when n >= 10 do | |
change(increment_for(values, 10), n - 10) | |
end | |
defp change(values, n) when n >= 5 do | |
change(increment_for(values, 5), n - 5) | |
end | |
defp change(values, n) do | |
change(increment_for(values, 1), n - 1) | |
end | |
defp increment_for(values, coin) do | |
Map.update!(values, coin, &(&1 + 1)) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment