Created
March 19, 2012 21:35
-
-
Save mikeebert/2127291 to your computer and use it in GitHub Desktop.
Coin Changer Kata
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
# Spec Step 1 | |
describe CoinChanger do | |
it "should return a penny" do | |
CoinChanger.make_change(1).should == %w(p) | |
end | |
end | |
# Class Step 1 - after failed uninitialized constant, failed no method errors, failed wrong number of arguments and | |
# failed 'got nil expected ["p"]' | |
class CoinChanger | |
def self.make_change(n) | |
["p"] | |
end | |
end | |
# Spec Step 2 | |
describe CoinChanger do | |
it "should return a penny" do | |
CoinChanger.make_change(1).should == %w(p) | |
end | |
it "should return two pennies" do | |
CoinChanger.make_change(2).should == %w(p p) | |
end | |
end | |
# Class Step 2 - after failed 'got ["p"] expected ["p" "p"] | |
class CoinChanger | |
def self.make_change(n) | |
if n == 1 | |
["p"] | |
else | |
%w(p p) | |
end | |
end | |
end | |
# Spec Step 3 | |
describe CoinChanger do | |
it "should return a penny" do | |
CoinChanger.make_change(1).should == %w(p) | |
end | |
it "should return two pennies" do | |
CoinChanger.make_change(2).should == %w(p p) | |
end | |
it "should return three pennies" do | |
CoinChanger.make_change(3).should == %w(p p) | |
end | |
end | |
# Class Step 3 - after failed 'got ["p" "p"] expected ["p" "p" "p"]' | |
class CoinChanger | |
def self.make_change(n) | |
change = [] | |
n.each do |penny| | |
change << "p" | |
end | |
return change | |
end | |
end | |
# Class Refactor 1 - Wait a minute, that block is ugly! I'm not even using the "penny" variable | |
class CoinChanger | |
def self.make_change(n) | |
change = [] | |
n.times {change << "p"} | |
return change | |
end | |
end | |
#Spec Step 4 | |
describe CoinChanger do | |
..previous three tests.. | |
it "should return a nickel" do | |
CoinChanger.make_change(5).should == %w(n) | |
end | |
end | |
# Class Step 4 - after failed 'got ["p" "p" "p" "p" "p"] expected ["n"]' | |
class CoinChanger | |
def self.make_change(n) | |
change = [] | |
if n == 5 | |
change << "n" | |
else | |
n.times {change << "p"} | |
end | |
return change | |
end | |
end | |
# Spec Refactor 1 - my fingers are getting tired of typing all the "it should" and CoinChanger.make_change(n) | |
# when the only things that are changing on each test is the amount of money we want to make change for and the | |
# array of the coins. I'm going to create a block with two variables to represent the amount and the coins and then | |
# interpolate those variables right into the text of my "it should" statement. | |
describe CoinChanger do | |
[[1, %w(p)], | |
[2, %w(p p)], | |
[3, %w(p p p)], | |
[5, %w(n)] | |
].each do |amount, coins| | |
it "should return #{coins} for #{amount} cent(s)" do | |
CoinChanger.make_change(amount).should == coins | |
end | |
end | |
end | |
# Spec Step 5 | |
describe CoinChanger do | |
[..previous amounts.., | |
[6, %w(n p)] | |
].each do |amount, coins| | |
it "should return #{coins} for #{amount} cent(s)" do | |
CoinChanger.make_change(amount).should == coins | |
end | |
end | |
end | |
# Class Step 5 - after failed 'got ["n"] expected ["n" "p"]' | |
class CoinChanger | |
def self.make_change(n) | |
change = [] | |
if n >= 5 | |
change << "n" | |
n = n % 5 | |
else | |
n.times {change << "p"} | |
end | |
return change | |
end | |
end | |
# Spec Step 6 | |
describe CoinChanger do | |
[..previous amounts.., | |
[10, %w(d)] | |
].each do |amount, coins| | |
it "should return #{coins} for #{amount} cent(s)" do | |
CoinChanger.make_change(amount).should == coins | |
end | |
end | |
end | |
# Class Step 6 - after failed 'got ["n" "n"] expected ["d"] | |
class CoinChanger | |
def self.make_change(n) | |
change = [] | |
if n >= 10 | |
change << "d" | |
n = n % 10 | |
end | |
if n >= 5 | |
change << "n" | |
n = n % 5 | |
end | |
n.times {change << "p"} | |
return change | |
end | |
end | |
# Spec Step 7 | |
describe CoinChanger do | |
[[1, %w(p)], | |
[2, %w(p p)], | |
[5, %w(n)], | |
[6, %w(n p)], | |
[10, %w(d)], | |
[20, %w(d d)] | |
].each do |amount, coins| | |
it "should return #{coins} for #{amount} cent(s)" do | |
CoinChanger.make_change(amount).should == coins | |
end | |
end | |
end | |
# Class Step 7 - after failed 'got ["d"] expected ["d" "d"] | |
class CoinChanger | |
def self.make_change(n) | |
change = [] | |
if n >= 10 | |
amount = n / 10 | |
amount.times {change << "d"} | |
n = n % 10 | |
end | |
if n >= 5 | |
change << "n" | |
n = n % 5 | |
end | |
n.times {change << "p"} | |
return change | |
end | |
end | |
# Class Refactor 2 - There's a lot of repition going on up there... Based on the previous Spec refactor of using | |
# two variables in a block, I'm going to set up a Hash of coins where the key equals the amount and value is the | |
# coin. Then we'll go ahead and shovel in the number of coins of a denomnination into change, reset n to the | |
# remainder, and repeat the process for the next lowest denomination. | |
class CoinChanger | |
@coins = {10 => "d", | |
5 => "n", | |
1 => "p"} | |
def self.make_change(n) | |
change = [] | |
@coins.each do |key, value| | |
amount = n / key | |
amount.times {change << value} | |
n = n % key | |
end | |
return change | |
end | |
end | |
# And at this point it's pretty much "solved". We can test for any amount with any denomination of coins and as | |
# long as those coins are listed in descending order in the @coins hash we will get the lowest number of coins back. | |
# "Final" Draft of Class and Spec | |
class CoinChanger | |
@coins = {25 => "q", | |
10 => "d", | |
5 => "n", | |
1 => "p"} | |
def self.make_change(n) | |
change = [] | |
@coins.each do |key, value| | |
amount = n / key | |
amount.times {change << value} | |
n = n % key | |
end | |
return change | |
end | |
end | |
describe CoinChanger do | |
[[1, %w(p)], | |
[2, %w(p p)], | |
[5, %w(n)], | |
[6, %w(n p)], | |
[10, %w(d)], | |
[11, %w(d p)], | |
[16, %w(d n p)], | |
[20, %w(d d)], | |
[21, %w(d d p)], | |
[25, %w(q)], | |
[26, %w(q p)], | |
[30, %w(q n)], | |
[31, %w(q n p)], | |
[36, %w(q d p)], | |
[40, %w(q d n)], | |
[41, %w(q d n p)], | |
[50, %w(q q)] | |
].each do |number, change| | |
it "should return #{change} for #{number} cents" do | |
CoinChanger.make_change(number).should == change | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment