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