Today I met up with Tim Dalton to do some pair programming on a scala kata… partial because I wanted to exercise both my scala and pair programming skills, partially because I wanted to steal some of Tim’s expertise to help me learn scala better. Since lunches are usually crammed and I expected us to be pressed for time, I selected a simple code kata: finding perfect numbers.
So to start, I wrote the first example, 5 is not a perfect number:
object PerfectNumbersSpec extends Specification{
"Perfect Numbers" should{
"5 is not a perfect number" in {
IsPerfectNumber(5) must be(false)
}
}
}
Following the rule of doing the simplest thing to make it pass, we just returned false:
object IsPerfectNumber extends (Int => Boolean) {
def apply(n:Int) = false
}
Next we wrote an example of 6 being identified as a perfect number, in which I just returned n % 2 ==0. Since this felt like cheating, the next step was an example of numbers that are not perfect numbers in the range of 1 to 10:
"if its not a perfect number should return false" in {
(1 to 10).filter(_ != 6).foreach(n =>
IsPerfectNumber(n) must be(false)
)
}
My cheat of returning n mod 2 no longer worked, so I did the first thing that came to mind:
object IsPerfectNumber extends (Int => Boolean) {
def apply(n:Int) = {
if(n % 2 == 0) (1 to n / 2).foldLeft(0)(_+_) == n else false
}
}
All examples passed, so I took my turn to writing the next example:
"28 is a perfect number" in {
IsPerfectNumber(28) must be(true)
}
to which Tim showed off his scala skills by converting my previous code to the following:
object IsPerfectNumber extends (Int => Boolean) {
def apply(n:Int) = {
(1 to n / 2).filter (n % _ == 0).foldLeft(0)(_+_) == n
}
}
For the scala impaired, that creates a range of numbers of one to n divided by two, filters it out to find only the divisors, then calls foldLeft which adds all of the divisors together. The example passed, so we added a couple more checks to be sure and it all went well. Here’s the specification in it’s entirety:
import org.specs._
object PerfectNumbersSpec extends Specification{
"Perfect Numbers" should{
"5 is not a perfect number" in {
IsPerfectNumber(5) must be(false)
}
"6 is a perfect number" in {
IsPerfectNumber(6) must be(true)
}
"28 is a perfect number" in {
IsPerfectNumber(28) must be(true)
}
"496 is a perfect number" in {
IsPerfectNumber(496) must be(true)
}
"8128 is a perfect number" in {
IsPerfectNumber(8128) must be(true)
}
"if its not a perfect number should return false" in {
(1 to 500).filter(!List(6,28,496).contains(_)).foreach(n =>
IsPerfectNumber(n) must be(false)
)
}
}
}
It was definitely a fun experience and we finished the kata fairly quickly (I think 20 minutes or so). I’m planning to do a few more scala kata lunches!


I love the simplicity of the code. Thanks for this great sample.
Hi James,
Since Scala 2.8, then the expression .foldLeft(0)(_+_) can be reduced to .sum.
If you are using Scalaz, then you can use ∑ (which I prefer).
Thanks Tony. I downloaded scalaz last week but have not folled around with it yet. Hopefully I’ll have a chance to this week.