Created
March 23, 2011 16:35
-
-
Save kings13y/883407 to your computer and use it in GitHub Desktop.
Sample solution to standard bowling kata (http://codingdojo.org/cgi-bin/wiki.pl?KataBowling) using Scala pattern matching and extractors
This file contains hidden or 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
// Idiomatic solution using extrators | |
// Extractors allow us to bind parameters to an object and are usable in pattern matches to see if a pattern can apply to the params submitted. | |
// Note this is simialr to case classes, but works against an Object (which are like 'static' classes in Java). Also it incurs some performance penalties | |
// as opposed to using case classes | |
class BowlingForExtractors() { | |
def score(bowls:List[Int]) = scoreFrames(bowls).slice(0,10).sum // take the first 10 elements from the List and sum them..any additional elements are the result of additional strikes | |
def scoreFrames(bowls:List[Int]) : List[Int] = bowls match { | |
case Nil => List(0) | |
case isStrike() => | |
bowls.slice(0,3).sum :: scoreFrames(bowls drop 1) // :: is the cons operator and is right associative. Basically it prepends | |
case isSpare() => | |
bowls.slice(0,3).sum :: scoreFrames(bowls drop 2) // elements to the left to the start of a List. the drop 'infix' operator | |
case _ => | |
bowls.slice(0,2).sum :: scoreFrames(bowls drop 2) // removes the named number of elements from the start of the List | |
} | |
object isStrike { // typical extractors would implement an apply method for creating an object instance based on params passed in.. | |
def unapply(bowls:List[Int]) = bowls match { | |
case 10::_ => true | |
case _ => false | |
} | |
} | |
object isSpare { | |
def unapply(bowls:List[Int]) = bowls match { | |
case a::b::_ if a+b == 10 => true | |
case _ => false | |
} | |
} | |
} | |
object BowlingKataRunner { | |
val allFoursAndFives = List(4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5) // Should == 90 | |
val allFives = List(5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5) // Should == 150 | |
val allStrikes = List(10,10,10,10,10,10,10,10,10,10,10,10) // Should == 300 | |
def main(args: Array[String]) { | |
val extractorSolution = new BowlingForExtractors() | |
println("Testing Bowling using extractors....") | |
println("4s and 5s: " + ((extractorSolution score allFoursAndFives) == 90)) | |
println("All 5s: " + ((extractorSolution score allFives) == 150) ) | |
println("All Strikes: " + ((extractorSolution score allStrikes) == 300) ) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment