Skip to content

Instantly share code, notes, and snippets.

@toreriklinnerud
Created September 7, 2009 19:32
Show Gist options
  • Save toreriklinnerud/182529 to your computer and use it in GitHub Desktop.
Save toreriklinnerud/182529 to your computer and use it in GitHub Desktop.
# Needs Ruby 1.8.7+ for built in #group_by and #reduce
# Implementation
Product = Struct.new(:code, :name, :price) do
def line_total(quantity)
price * quantity
end
end
class Checkout
def initialize(products)
@products = products.group_by{|product| product.code}
@items = []
end
def scan(item)
@items << item
end
def total
@items.group_by(&:to_s).map do |code, list|
product = @products[code.downcase.to_sym].first
product.line_total(list.length)
end.reduce(:+)
end
end
# Product defintions
fruit_tea = Product.new(:fr1, 'Fruit tea', 3.11)
strawberries = Product.new(:sr1, 'Strawberries', 5.00)
coffee = Product.new(:cf1, 'Coffee', 11.23)
products = [fruit_tea, strawberries, coffee]
def fruit_tea.line_total(quantity)
price * ((quantity.to_i + 1) / 2)
end
def strawberries.line_total(quantity)
return super if quantity < 3
quantity * 4.50
end
# Tests
Checkout.new(products).instance_eval do
scan('FR1')
scan('SR1')
scan('FR1')
scan('FR1')
scan('CF1')
puts total
end
Checkout.new(products).instance_eval do
scan('FR1')
scan('FR1')
puts total
end
Checkout.new(products).instance_eval do
scan('SR1')
scan('SR1')
scan('FR1')
scan('SR1')
puts total
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment