Skip to content

Instantly share code, notes, and snippets.

@jhannes
Created March 20, 2012 19:31
Show Gist options
  • Save jhannes/2140246 to your computer and use it in GitHub Desktop.
Save jhannes/2140246 to your computer and use it in GitHub Desktop.
Potter kata tests
class ShoppingCart
constructor: (@items)->
@counts = (count for item,count of @items).sort().reverse()
totalPrice: -> @subTotal() - @discount()
subTotal: ->
result = 0
result += count*8 for item,count of @items
result
discount: ->
@discountForSetOfSize(2, 5) +
@discountForSetOfSize(3, 10) +
@discountForSetOfSize(4, 20) +
@discountForSetOfSize(5, 25)
discountForSetOfSize: (setsize, discountPercent)->
countForSet = (@counts[setsize-1] || 0) - (@counts[setsize] || 0)
countForSet * 8 * discountPercent * setsize / 100.0
exports.ShoppingCart = ShoppingCart
ShoppingCart = exports.ShoppingCart
describe 'Shopping discount', ->
it "calculates subtotal", ->
cart = new ShoppingCart({first:10, second:20})
expect(cart.subTotal()).toEqual(30*8)
it "calculates discount for sets of two", ->
cart = new ShoppingCart({first:100,second:100})
expect(cart.discount()).toEqual(2*5*8)
it "only include whole sets in discount", ->
cart = new ShoppingCart({first:100,second:1000})
expect(cart.discount()).toEqual(2*5*8)
it "doesn't give discount for single item", ->
cart = new ShoppingCart({first:1})
expect(cart.discount()).toEqual(0)
it "calculates discount for sets of three", ->
cart = new ShoppingCart({first:100,second:100,third:100})
expect(cart.discount()).toEqual(3*10*8)
it "calculates discount for sets of four", ->
cart = new ShoppingCart({first:100,second:100,third:100,four:100})
it "calculates discount for sets of five", ->
cart = new ShoppingCart({first:100,second:100,third:100,four:100,fifth:100})
expect(cart.discount()).toEqual(5*25*8)
it "calculates total price", ->
cart = new ShoppingCart({first:100,second:1000})
expect(cart.totalPrice()).toEqual(1100*8 - 2*5*8)
it "calculates price for example shopping cart", ->
cart = new ShoppingCart({first:2,second:2,third:2,fourth:1,fifth:1})
expect(cart.totalPrice()).toEqual((2+2+2+1+1)*8 - (5*8*25/100.0 + 3*8*10/100.0))
it "finds sets", ->
cart = new exports.ShoppingCart({"foo":1, "bar":3, "baz":3, "gaz":5, "qux": 7})
expect(cart.setsOf(6)).toEqual(0)
expect(cart.setsOf(5)).toEqual(1) # foo
expect(cart.setsOf(4)).toEqual(2) # bar, baz
expect(cart.setsOf(3)).toEqual(0) #
expect(cart.setsOf(2)).toEqual(2) # gaz, qux
expect(cart.setsOf(1)).toEqual(2) # qux
@tarvaina
Copy link

I'd test e.g. 5+1, then 5+2, then 5+2+2, then 5+3/4+4 then 5+5+3+3/4+4+4+4.

@jhannes
Copy link
Author

jhannes commented Mar 20, 2012

Ick! That's why it was different from the given solution. Is there any way to calculate this, or should one just try out all combinations?

@tarvaina
Copy link

That way you can go from special cases to iteration/recursion.

@jhannes
Copy link
Author

jhannes commented Mar 20, 2012

Stupid discount structure. :-(

;-)

@tarvaina
Copy link

I don't know an algorithm for this that is simple, efficient and obvious.

@jhannes
Copy link
Author

jhannes commented Mar 20, 2012

Cool. I'll keep that in mind next time I try it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment