So I was looking for some simple yet interesting problems to solve that would help me explore the power of Scala. That lead me to ProjectEuler.net. I would highly recommend this site to anyone interested in puzzle solving. The problem I started with was as follows:
"What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?"
The problem is simple enough, but I the goal was to solve the problem in a "Functional" way so as to utilize the power of Scala. So no loops!
Following is the final code listing that solves this problem without using any loops. Also, I tried to avoid any "var"iables but some "val"use are used for efficiency. But then that is the power of Scala to combine functional with non-functional code!
"What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?"
The problem is simple enough, but I the goal was to solve the problem in a "Functional" way so as to utilize the power of Scala. So no loops!
Following is the final code listing that solves this problem without using any loops. Also, I tried to avoid any "var"iables but some "val"use are used for efficiency. But then that is the power of Scala to combine functional with non-functional code!
import scala.collection.mutable.HashMap
object Divisibility {
val range = 2 to 20 // Range of numbers we are working on
val primes = range.filter(prime(_)) // Prime numbers in the range
// Test for prime number (Note: can be faster if tested until sqrt(n) instead of n/2
def prime(n:Int): Boolean = n match {
case 1 => false
case _ => !(2 to scala.math.ceil(n/2).toInt).exists( n % _ == 0)
}
// Function that returns a list of prime factors of a given integer
def factorize(n:Int): List[Int] = primes.find(n%_==0) match {
case Some(p) => p::factorize(n/p)
case None => Nil
}
// Function that returns the powers of prime factors of a number
def factorCount(n:Int): List[Int] = {
val factors = factorize(n)
return primes.map(p => factors.count(_==p)).toList
}
// Element-wise maximum list for two lists
def listMax(l1:List[Int], l2:List[Int]): List[Int] = (l1 zip l2).map(x => scala.math.max(x._1,x._2))
// Main function to calculate the required value "v"
def main(args: Array[String]): Unit = {
val maxFactors = (range.map(factorCount(_))).reduce(listMax(_,_))
val v = (primes zip maxFactors).map(x => scala.math.pow(x._1,x._2).toInt).reduce(_*_)
println(v)
}
}
No comments:
Post a Comment