Skip to content

Instantly share code, notes, and snippets.

@damonkelley
Last active May 23, 2017 03:19
Show Gist options
  • Save damonkelley/029420d0ba7fd48db63c4a9f041b2df4 to your computer and use it in GitHub Desktop.
Save damonkelley/029420d0ba7fd48db63c4a9f041b2df4 to your computer and use it in GitHub Desktop.
Change Maker in Elixir - with and without a macro
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
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
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