class FirstKata { def sum: Int = { var sum = 0; for (i <- 1 until 1000) { if (i % 3 == 0 || i % 5 == 0) sum = sum + i } sum } }
class FirstKataTest extends Assertions { @Test def sum() { val kata = new FirstKata assertEquals(kata.sum, 233168) } }
This solution is very similar to the java one except for the fact that was written in scala.
Lets perform a serie of little refactoring in order to get the more generic solution we are capable of.
class FirstKata { def sum(upperLimit: Int): Int = { var sum: Int = 0; for (i <- 1 until upperLimit) { if (i % 3 == 0 || i % 5 == 0) sum = sum + i } sum } }
class FirstKataTest extends Assertions { @Test def sum() { val kata = new FirstKata assertEquals(kata sum 10, 23) assertEquals(kata sum 1000, 233168) } }
The first refactoring added the upperLimit parameter.
class FirstKata { def sum(upperLimit: Int, multiples: Seq[Int]): Int = { var sum: Int = 0; for (i <- 1 until upperLimit) { if (isMultiple(i, multiples)) sum = sum + i } sum } def isMultiple(upperLimit: Int, multiples: Seq[Int]): Boolean = { for (multiple <- multiples) { if (upperLimit % multiple == 0) return true } return false } }
class FirstKataTest extends Assertions { @Test def sum() { val kata = new FirstKata assertEquals(kata.sum(10, 3::5::Nil), 23) assertEquals(kata.sum(1000, 3::5::Nil), 233168) } }
The second refactoring add the multiples parameter as a Seq[Int].
class FirstKata { def sum(upperLimit: Int, multiples: Seq[Int]): Int = { var sum: Int = 0; for (i <- 1 until upperLimit if isMultiple(i, multiples)) yield sum = sum + i sum } def isMultiple(upperLimit: Int, multiples: Seq[Int]): Boolean = { if (multiples.filter(upperLimit % _ == 0).isEmpty) false else true } }
In this refactoring we made use of for comprehension to get a more concise solution
class FirstKata { def sum(upperLimit: Int, mult: Seq[Int]): Int = upperLimit match { case 0 => 0 case x => if (isMultiple(x, mult)) (x + sum((x - 1), mult)) else sum((x - 1), mult) } def isMultiple(upperLimit: Int, multiples: Seq[Int]): Boolean = { if (multiples.filter(upperLimit % _ == 0).isEmpty) false else true } }
Now using pattern matching. It illustrates the what one can get using FP.
And at last but not least.
class FirstKata { def sum(upperLimit: Int, multiples: Seq[Int]): Int = { List.range(1, upperLimit) .filter(isMultiple(_, multiples)).foldLeft(0)(_ + _) } def isMultiple(upperLimit: Int, multiples: Seq[Int]): Boolean = { if (multiples.filter(upperLimit % _ == 0).isEmpty) false else true } }
A more concise solution.
No comments:
Post a Comment