I'm trying to write a method that calculates the mean of the elements in a given List in Scala. Here's my code:
def meanElements(list: List[Float]): Float = {
list match {
case x :: tail => (x + meanElements(tail))/(list.length)
case Nil => 0
}
}
When I call meanElements(List(10,12,14))), the result I get is different than 12. Can someone help?
You can simply do it using inbuilt functions:
scala> def mean(list:List[Int]):Int =
| if(list.isEmpty) 0 else list.sum/list.size
mean: (list: List[Int])Int
scala> mean(List(10,12,14))
res1: Int = 12
scala>
The formula is not correct, it should be:
case x :: tail => (x + meanElements(tail) * tail.length) / list.length
But this implementation is performing a lot of divisions and multiplications.
It would be better to split the computation of the mean to two steps,
calculating the sum first,
and then dividing by list.length.
That is, something more like this:
def meanElements(list: List[Float]): Float = sum(list) / list.length
Where sum is a helper function you have to implement.
If you don't want to expose its implementation,
then you can define it in the body of meanElements.
(Or as #ph88 pointed out,
it could be as simple as list.reduce(_ + _).)
Suppose I have this code in scala :
def factorial(accumulator: Int, x: Int) : Int = {
if(x == 1)
return accumulator
factorial(x * accumulator, x - 1)
}
println(factorial(1,0))
And the Output :
0
Now I have two questions :
1) Isn't the definition of this function fundamentally wrong? ( will not give the right answer for zero) I could always wrap this function inside another function and treat zero as special case returning 1 but that does not feel right and in tune with the formal definition.
2) Also why I am returned 0 as the answer in the first place? Why doesn't the code get stuck in an infinite loop?
def factorial(x: Int): Int = {
#annotation.tailrec
def factorial(accumulator: Int, x: Int): Int = {
if (x <= 0)
accumulator
else
factorial(x * accumulator, x - 1)
}
assert(x >= 0,"""argument should be "non-negative integer" """)
factorial(1, x)
}
You should not give user possibility to call factorial in wrong way. So your function should be internal
factorial(0) = 1
Yes, you should hide the accumulator and make it an argument of an internal, tailrec function. The special case for zero should also be handled explicitly, there is nothing 'against formal factorial definition' with it.
It works because integer exceeds the maximum negative value.
Many numerical problems are of the form:
initialize: x_0 = ...
iterate: x_i+1 = function(x_i) until convergence, e.g.,
|| x_i+1 - x_i || < epsilon
I'm wondering whether there is a nice way to write such an algorithm using idiomatic Scala. The nature of the problem calls for an Iterator or Stream. However, my current take on this looks really ugly:
val xFinal = Iterator.iterate(xInit) { x_i =>
// update x_i+1
}.toList // necessary to pattern match within takeWhile
.sliding(2) // necessary since takeWhile needs pair-wise comparison
.takeWhile{ case x_i :: x_iPlus1 :: Nil => /* convergence condition */ }
.toList // since the outer container is still an Iterator
.last // to get the last element of the iteration
.last // to get x_iPlus1
This is not only ugly, the pattern matching in takeWhile also causes a warning. Obviously I do not have to pattern-match here, but I would love to keep a strong resemblance to the mathematical original.
Any ideas to make this look more beautiful?
The following minimalist (silly) example may illustrate none the less a useful framework to adapt,
def function (i:Int): Int = i+1
def iter (x0: Int): Int = {
val x1 = function(x0)
if (x1 - x0 == 1) x1 else iter(x1)
}
Here is my solution for the example of finding the square root using Newton's method, which reduces in this case to the Babylonian method:
import math.abs
val tol=0.00001
val desiredSqRoot=256
val xFinal = Iterator.iterate(1.0) { x => 0.5*(x+desiredSqRoot/x) }
def converged(l: Seq[Double]): Boolean = l match{
case x_old :: x_new :: Nil => if( abs(x_old-x_new)/x_old < tol ) true else false
case _ => true
}
xFinal.sliding(2).dropWhile( x=> !converged(x) ).next.last
which results as:
scala> xFinal.sliding(2).dropWhile( x=> !converged(x) ).next.last
res23: Double = 16.00000000000039
In this example we know the value it should converge to, yet I've written the convergence criterion without this knowledge, because in general we don't know this.
I was wondering if there is some general method to convert a "normal" recursion with foo(...) + foo(...) as the last call to a tail-recursion.
For example (scala):
def pascal(c: Int, r: Int): Int = {
if (c == 0 || c == r) 1
else pascal(c - 1, r - 1) + pascal(c, r - 1)
}
A general solution for functional languages to convert recursive function to a tail-call equivalent:
A simple way is to wrap the non tail-recursive function in the Trampoline monad.
def pascalM(c: Int, r: Int): Trampoline[Int] = {
if (c == 0 || c == r) Trampoline.done(1)
else for {
a <- Trampoline.suspend(pascal(c - 1, r - 1))
b <- Trampoline.suspend(pascal(c, r - 1))
} yield a + b
}
val pascal = pascalM(10, 5).run
So the pascal function is not a recursive function anymore. However, the Trampoline monad is a nested structure of the computation that need to be done. Finally, run is a tail-recursive function that walks through the tree-like structure, interpreting it, and finally at the base case returns the value.
A paper from RĂșnar Bjanarson on the subject of Trampolines: Stackless Scala With Free Monads
In cases where there is a simple modification to the value of a recursive call, that operation can be moved to the front of the recursive function. The classic example of this is Tail recursion modulo cons, where a simple recursive function in this form:
def recur[A](...):List[A] = {
...
x :: recur(...)
}
which is not tail recursive, is transformed into
def recur[A]{...): List[A] = {
def consRecur(..., consA: A): List[A] = {
consA :: ...
...
consrecur(..., ...)
}
...
consrecur(...,...)
}
Alexlv's example is a variant of this.
This is such a well known situation that some compilers (I know of Prolog and Scheme examples but Scalac does not do this) can detect simple cases and perform this optimisation automatically.
Problems combining multiple calls to recursive functions have no such simple solution. TMRC optimisatin is useless, as you are simply moving the first recursive call to another non-tail position. The only way to reach a tail-recursive solution is remove all but one of the recursive calls; how to do this is entirely context dependent but requires finding an entirely different approach to solving the problem.
As it happens, in some ways your example is similar to the classic Fibonnaci sequence problem; in that case the naive but elegant doubly-recursive solution can be replaced by one which loops forward from the 0th number.
def fib (n: Long): Long = n match {
case 0 | 1 => n
case _ => fib( n - 2) + fib( n - 1 )
}
def fib (n: Long): Long = {
def loop(current: Long, next: => Long, iteration: Long): Long = {
if (n == iteration)
current
else
loop(next, current + next, iteration + 1)
}
loop(0, 1, 0)
}
For the Fibonnaci sequence, this is the most efficient approach (a streams based solution is just a different expression of this solution that can cache results for subsequent calls). Now,
you can also solve your problem by looping forward from c0/r0 (well, c0/r2) and calculating each row in sequence - the difference being that you need to cache the entire previous row. So while this has a similarity to fib, it differs dramatically in the specifics and is also significantly less efficient than your original, doubly-recursive solution.
Here's an approach for your pascal triangle example which can calculate pascal(30,60) efficiently:
def pascal(column: Long, row: Long):Long = {
type Point = (Long, Long)
type Points = List[Point]
type Triangle = Map[Point,Long]
def above(p: Point) = (p._1, p._2 - 1)
def aboveLeft(p: Point) = (p._1 - 1, p._2 - 1)
def find(ps: Points, t: Triangle): Long = ps match {
// Found the ultimate goal
case (p :: Nil) if t contains p => t(p)
// Found an intermediate point: pop the stack and carry on
case (p :: rest) if t contains p => find(rest, t)
// Hit a triangle edge, add it to the triangle
case ((c, r) :: _) if (c == 0) || (c == r) => find(ps, t + ((c,r) -> 1))
// Triangle contains (c - 1, r - 1)...
case (p :: _) if t contains aboveLeft(p) => if (t contains above(p))
// And it contains (c, r - 1)! Add to the triangle
find(ps, t + (p -> (t(aboveLeft(p)) + t(above(p)))))
else
// Does not contain(c, r -1). So find that
find(above(p) :: ps, t)
// If we get here, we don't have (c - 1, r - 1). Find that.
case (p :: _) => find(aboveLeft(p) :: ps, t)
}
require(column >= 0 && row >= 0 && column <= row)
(column, row) match {
case (c, r) if (c == 0) || (c == r) => 1
case p => find(List(p), Map())
}
}
It's efficient, but I think it shows how ugly complex recursive solutions can become as you deform them to become tail recursive. At this point, it may be worth moving to a different model entirely. Continuations or monadic gymnastics might be better.
You want a generic way to transform your function. There isn't one. There are helpful approaches, that's all.
I don't know how theoretical this question is, but a recursive implementation won't be efficient even with tail-recursion. Try computing pascal(30, 60), for example. I don't think you'll get a stack overflow, but be prepared to take a long coffee break.
Instead, consider using a Stream or memoization:
val pascal: Stream[Stream[Long]] =
(Stream(1L)
#:: (Stream from 1 map { i =>
// compute row i
(1L
#:: (pascal(i-1) // take the previous row
sliding 2 // and add adjacent values pairwise
collect { case Stream(a,b) => a + b }).toStream
++ Stream(1L))
}))
The accumulator approach
def pascal(c: Int, r: Int): Int = {
def pascalAcc(acc:Int, leftover: List[(Int, Int)]):Int = {
if (leftover.isEmpty) acc
else {
val (c1, r1) = leftover.head
// Edge.
if (c1 == 0 || c1 == r1) pascalAcc(acc + 1, leftover.tail)
// Safe checks.
else if (c1 < 0 || r1 < 0 || c1 > r1) pascalAcc(acc, leftover.tail)
// Add 2 other points to accumulator.
else pascalAcc(acc, (c1 , r1 - 1) :: ((c1 - 1, r1 - 1) :: leftover.tail ))
}
}
pascalAcc(0, List ((c,r) ))
}
It does not overflow the stack but as on big row and column but Aaron mentioned it's not fast.
Yes it's possible. Usually it's done with accumulator pattern through some internally defined function, which has one additional argument with so called accumulator logic, example with counting length of a list.
For example normal recursive version would look like this:
def length[A](xs: List[A]): Int = if (xs.isEmpty) 0 else 1 + length(xs.tail)
that's not a tail recursive version, in order to eliminate last addition operation we have to accumulate values while somehow, for example with accumulator pattern:
def length[A](xs: List[A]) = {
def inner(ys: List[A], acc: Int): Int = {
if (ys.isEmpty) acc else inner(ys.tail, acc + 1)
}
inner(xs, 0)
}
a bit longer to code, but i think the idea i clear. Of cause you can do it without inner function, but in such case you should provide acc initial value manually.
I'm pretty sure it's not possible in the simple way you're looking for the general case, but it would depend on how elaborate you permit the changes to be.
A tail-recursive function must be re-writable as a while-loop, but try implementing for example a Fractal Tree using while-loops. It's possble, but you need to use an array or collection to store the state for each point, which susbstitutes for the data otherwise stored in the call-stack.
It's also possible to use trampolining.
It is indeed possible. The way I'd do this is to
begin with List(1) and keep recursing till you get to the
row you want.
Worth noticing that you can optimize it: if c==0 or c==r the value is one, and to calculate let's say column 3 of the 100th row you still only need to calculate the first three elements of the previous rows.
A working tail recursive solution would be this:
def pascal(c: Int, r: Int): Int = {
#tailrec
def pascalAcc(c: Int, r: Int, acc: List[Int]): List[Int] = {
if (r == 0) acc
else pascalAcc(c, r - 1,
// from let's say 1 3 3 1 builds 0 1 3 3 1 0 , takes only the
// subset that matters (if asking for col c, no cols after c are
// used) and uses sliding to build (0 1) (1 3) (3 3) etc.
(0 +: acc :+ 0).take(c + 2)
.sliding(2, 1).map { x => x.reduce(_ + _) }.toList)
}
if (c == 0 || c == r) 1
else pascalAcc(c, r, List(1))(c)
}
The annotation #tailrec actually makes the compiler check the function
is actually tail recursive.
It could be probably be further optimized since given that the rows are symmetric, if c > r/2, pascal(c,r) == pascal ( r-c,r).. but left to the reader ;)
I would like to know, if there is a Scala built-in method to get the length of the decimal representation of an integer ?
Example: 45 has length 2; 10321 has length 5.
One could get the length with 10321.toString.length, but this smells a bit because of the overhead when creating a String object. Is there a nicer way or a built-in method ?
UPDATE:
With 'nicer' I mean a faster solution
I am only interested in positive integers
This is definitely personal preference, but I think the logarithm method looks nicer without a branch. For positive values only, the abs can be omitted of course.
def digits(x: Int) = {
import math._
ceil(log(abs(x)+1)/log(10)).toInt
}
toString then get length of int will not work for negative integers. This code will work not only for positive numbers but also negatives.
def digits(n:Int) = if (n==0) 1 else math.log10(math.abs(n)).toInt + 1;
If you want speed then something like the following is pretty good, assuming random distribution:
def lengthBase10(x: Int) =
if (x >= 1000000000) 10
else if (x >= 100000000) 9
else if (x >= 10000000) 8
else if (x >= 1000000) 7
else if (x >= 100000) 6
else if (x >= 10000) 5
else if (x >= 1000) 4
else if (x >= 100) 3
else if (x >= 10) 2
else 1
Calculating logarithms to double precision isn't efficient if all you want is the floor.
The conventional recursive way would be:
def len(x: Int, i: Int = 1): Int =
if (x < 10) i
else len(x / 10, i + 1)
which is faster than taking logs for integers in the range 0 to 10e8.
lengthBase10 above is about 4x faster than everything else though.
Something like this should do the job:
def numericLength(n: Int): Int = BigDecimal(n).precision
Take log to the base 10, take the floor and add 1.
The easiest way is:
def numberLength(i : Int): Int = i.toString.length
You might add a guarding-condition because negative Int will have the length of their abs + 1.
Another possibility can be:
private lazy val lengthList = (1 until 19).map(i => i -> math.pow(10, i).toLong)
def numberSize(x: Long): Int =
if (x >= 0) positiveNumberSize(x)
else positiveNumberSize(-x) + 1
private def positiveNumberSize(x: Long): Int =
lengthList
.collectFirst {
case (l, p) if x < p => l
}
.getOrElse(19)
Most people gave the most efficient answer of (int) log(number)+1
But I want to get a bit deeper into understanding why this works.
Let N be a 3 digit number. This means N can be any number between 100 and 1000, or :
100 < N < 1000
=> 10^2 < N < 10^3
The Logarithmic function is continuous , therefore :
log(10^2) < log(N) < log(10^3)
=> 2 < log(N) < 3
We can conclude that N's logarithm is a number between 2 and 3 , or in other words , any 3 digit numbers' logarithm is between 2 and 3.
So if we take only the integer part of a numbers logarithm(eg. the integer part of 2.567 is 2) and add 1 we get the digit length of the number.
Here is the solution:
number.toString.toCharArray.size
input - output
45 - 2
100 - 3