Skip to content

Instantly share code, notes, and snippets.

@helenwilliamson
Last active August 29, 2015 14:27
Show Gist options
  • Save helenwilliamson/16cec8b0996b5dcb08a7 to your computer and use it in GitHub Desktop.
Save helenwilliamson/16cec8b0996b5dcb08a7 to your computer and use it in GitHub Desktop.
/**
* Created by helen on 20/08/15.
*/
object HarryPotterBasket {
val pricingStrategies = List(TwoBooksPricingStrategy)
def calculate(basket: List[HarryPotterSeries]): Double = {
pricingStrategies.map(_.price(basket)).head.price.get
}
def calculate1(basket: PricingApplication) : Double = {
if (basket.remaining.isEmpty)
basket.price
else
//Todo: Get remaining basket and find strategy that matches.
}
}
sealed trait HarryPotterSeries
case object HarryPotterAndThePhilisophersStone extends HarryPotterSeries
case object HarryPotterAndTheChamberOfSecrets extends HarryPotterSeries
case object HarryPotterAndThePrisonerOfAsakban extends HarryPotterSeries
case object HarryPotterAndTheGobletOfFire extends HarryPotterSeries
case object HarryPotterAndTheOrderOfThePheniox extends HarryPotterSeries
case object HarryPotterAndTheHalfBloodPrince extends HarryPotterSeries
case object HarryPotterAndTheDeathlyHallows extends HarryPotterSeries
sealed trait HarryPotterPricingStrategy {
def price(basket : List[HarryPotterSeries]) : PricingApplication
}
case object TwoBooksPricingStrategy extends HarryPotterPricingStrategy {
def price(basket: List[HarryPotterSeries]) = {
if(basket.toSet.size >= 2) {
val firstBook = basket.head
PricingApplication(Some(15.20), Lists.removeFirst(basket.tail)(_ == firstBook))
} else {
PricingApplication(Option.empty, basket)
}
}
}
case object OneBookPricingStrategy extends HarryPotterPricingStrategy {
def price(basket: List[HarryPotterSeries]) = {
if (basket.nonEmpty) PricingApplication(Some(8), basket.tail)
else PricingApplication(None, basket);
}
}
case class PricingApplication(price: Option[Double], remaining: List[HarryPotterSeries])
object Lists {
def removeFirst[T](list: List[T])(predicate: (T) => Boolean): List[T] = {
val (before, atAndAfter) = list span (x => !predicate(x))
before ::: atAndAfter.drop(1)
}
}
/**
* Created by helen on 20/08/15.
*/
import org.scalatest.Matchers._
class HarryPotterBasketTest extends org.scalatest.FunSuite {
test("should apply discount for 2 books") {
val basket = List(HarryPotterAndThePhilisophersStone, HarryPotterAndTheOrderOfThePheniox)
HarryPotterBasket.calculate(basket) should be (15.2)
}
test("should apply discount for 3 books of 2 types") {
val basket = List(HarryPotterAndTheChamberOfSecrets, HarryPotterAndTheChamberOfSecrets, HarryPotterAndTheGobletOfFire)
HarryPotterBasket.calculate(basket) should be (23.2)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment