Skip to content

Instantly share code, notes, and snippets.

@rpkraemer
Created July 25, 2013 22:14
Show Gist options
  • Select an option

  • Save rpkraemer/6084267 to your computer and use it in GitHub Desktop.

Select an option

Save rpkraemer/6084267 to your computer and use it in GitHub Desktop.
ATM Ruby Studies
class NoSufficientPapers < StandardError
end
class Atm
def initialize(notes)
@notes = notes
end
def available_papers
available = []
@notes.each {|note, quantity| available << note.to_i if quantity > 0}
available
end
def withdraw(amount)
result = []
notes = calculate_papers(amount)
notes.each do |note, quantity|
raise NoSufficientPapers if not atm_has_available?(note, quantity) #Atm has not available the required note or quantity to to the withdraw
produce_quantity_of(note, quantity) do |note|
result << note
end
decrement_quantity_of_papers_of(note, quantity)
end
result
end
private
def calculate_papers(amount)
papers = {}
available_papers.each {|note| papers[note] = 0}
available_papers.each do |note|
papers[note] += amount / note
amount = amount % note
end
raise NoSufficientPapers if amount > 0 #Atm has not correcty calculate amount, because it has no needed papers to do it
papers
end
def decrement_quantity_of_papers_of(note, quantity)
@notes["#{note}"] -= quantity
end
def atm_has_available?(note, quantity)
@notes.has_key?("#{note}") && @notes["#{note}"] >= quantity
end
def produce_quantity_of(paper, quantity)
if block_given?
quantity.times { yield paper.to_i }
end
end
end
=begin
Desenvolva um programa que simule a entrega de notas quando um cliente efetuar um saque em um caixa eletrônico. Os requisitos básicos são os seguintes:
Entregar o menor número de notas;
É possível sacar o valor solicitado com as notas disponíveis;
Saldo do cliente infinito;
Quantidade de notas infinito (pode-se colocar um valor finito de cédulas para aumentar a dificuldade do problema);
Notas disponíveis de R$ 100,00; R$ 50,00; R$ 20,00 e R$ 10,00
Exemplos:
Valor do Saque: R$ 30,00 – Resultado Esperado: Entregar 1 nota de R$20,00 e 1 nota de R$ 10,00.
Valor do Saque: R$ 80,00 – Resultado Esperado: Entregar 1 nota de R$50,00 1 nota de R$ 20,00 e 1 nota de R$ 10,00.
Retirado do endereço: http://dojopuzzles.com/problemas/exibe/caixa-eletronico/
=end
require 'test/unit'
require 'atm'
class AtmTest < Test::Unit::TestCase
def setup
@atm = Atm.new '100' => 10, '50' => 10, '20' => 10, '10' => 10
end
def test_should_show_paper_money_available
assert_equal [100, 50, 20, 10], @atm.available_papers
end
def test_should_withdraw_10
assert_equal [10], @atm.withdraw(10)
end
def test_should_withdraw_30
assert_equal [20, 10], @atm.withdraw(30)
end
def test_should_withdraw_80
assert_equal [50, 20, 10], @atm.withdraw(80)
end
def test_should_withdraw_100
assert_equal [100], @atm.withdraw(100)
end
def test_should_withdraw_200
assert_equal [100, 100], @atm.withdraw(200)
end
def test_should_not_permit_withdraw_with_insufficient_papers
atm = Atm.new '100' => 10, '50' => 10, '20' => 10
assert_raise NoSufficientPapers do
atm.withdraw(10)
end
end
def test_should_not_permit_withdraw_insufficient_papers_2
# Has 10 notes, but only 2, need 3
atm = Atm.new '100' => 10, '50' => 10, '10' => 2
assert_raise NoSufficientPapers do
atm.withdraw(30)
end
end
def test_should_not_permit_withdraw_insufficient_papers_3
# Has 10 notes, but not 20
atm = Atm.new '100' => 1, '50' => 3, '20' => 3
assert_raise NoSufficientPapers do
atm.withdraw(260)
end
end
def test_should_withdraw_30_with_only_10_notes
# Has 10 notes, but not 20
atm = Atm.new '100' => 10, '50' => 10, '10' => 3
assert_equal [10, 10, 10], atm.withdraw(30)
assert_equal [100, 50], atm.available_papers
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment